求调,样例过不了orz
查看原帖
求调,样例过不了orz
254491
橙橙like海绵楼主2023/8/22 10:03
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int n,m,maxid[N<<2],minid[N<<2];
ll d[N],h[N],sum[N],maxx[N],minn[N];
inline ll read(){
    ll s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
int getmax(int x,int y){
    if(maxx[x]>maxx[y]) return x;
    else return y;
}
int getmin(int x,int y){
    if(minn[x]<minn[y]) return x;
    else return y;
}
void push_up(int k){
    maxid[k]=getmax(maxid[k<<1],maxid[k<<1|1]);
    minid[k]=getmin(minid[k<<1],minid[k<<1|1]);
}
void build(int k,int l,int r){
    if(l==r){
        maxid[k]=minid[k]=l;
        return ;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    push_up(k);
}
int query_max(int k,int l,int r,int x,int y){
    if(x<=l&&r<=y) return maxid[k];
    int mid=(l+r)>>1,res;
    if(x<=mid) res=query_max(k<<1,l,mid,x,y);
    if(mid<y) res=getmax(res,query_max(k<<1|1,mid+1,r,x,y));
    return res;
}
int query_min(int k,int l,int r,int x,int y){
    if(x<=l&&r<=y) return minid[k];
    int mid=(l+r)>>1,res;
    if(x<=mid) res=query_min(k<<1,l,mid,x,y);
    if(mid<y) res=getmin(res,query_min(k<<1|1,mid+1,r,x,y));
    return res;
}
int check_min(int l,int r){
    if(l>r) return 0;
    else return query_min(1,1,(n<<1|1),l,r);
}
int check_max(int l,int r){
    if(l>r) return 0;
    else return query_max(1,1,(n<<1|1),l,r);
}
ll  work(int l,int r){
    int x=check_min(l,r),y=check_max(l,r);
    if(x!=y) return maxx[y]-minn[x];
    int t1=getmin(check_min(l,x-1),check_min(x+1,r));
    int t2=getmax(check_max(l,y-1),check_max(y+1,r));
    return max(maxx[y]-minn[t1],maxx[t2]-minn[x]);
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++) d[i%n+1]=d[i%n+1+n]=read();
    for(int i=1;i<=n;i++) h[i+n]=h[i]=read();
    memset(maxx,-inf,sizeof(maxx));
    memset(minn,inf,sizeof(minn));
    for(int i=1;i<=(n<<1);i++){
        sum[i]=sum[i-1]+d[i];
        maxx[i]=sum[i]+(h[i]<<1);
        minn[i]=sum[i]-(h[i]<<1);
    } 
    //for(int i=1;i<=(n<<1);i++) printf("%lld %lld\n",maxx[i],minn[i]);
    build(1,1,(n<<1|1));
    int l,r;
    while(m--){
        l=read();r=read();
        if(l<=r) printf("%lld\n",work(r+1,l+n-1));
        else printf("%lld\n",work(r+1,l-1));
    }
    return 0;
}
2023/8/22 10:03
加载中...