• BZOJ 2653 middle


    题目链接:middle

      首先答案显然是可以二分的,把不小于当前二分的答案的位置设成(1),其余位置设为(-1),那么就是查询是否存在一段使得和非负。

      对于每个询问我们可以拆成三段,([a,b]),((b,c)),([c,d])。中间那段显然是要全部统计进去的,所以我们统计一下区间和。前面那段我们需要的是最大后缀和,后面那段我们需要的是最大前缀和。于是建主席树维护就好了。

      下面贴代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    #define pt(x,l,r) L=l,R=r,D=0,query(rt[x],1,n)
    #define maxn 20010
    #define MAXN 500010
    
    using namespace std;
    typedef long long llg;
    
    int n,m,a[maxn],d[maxn],ld,tt,rt[maxn],q[4],ans,N,D;
    int sumv[MAXN],le[MAXN],ri[MAXN],sl[MAXN],sr[MAXN],L,R;
    struct data{int x,y;}s[maxn];
    
    int getint(){
    	int w=0;bool q=0;
    	char c=getchar();
    	while((c>'9'||c<'0')&&c!='-') c=getchar();
    	if(c=='-') c=getchar(),q=1;
    	while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
    	return q?-w:w;
    }
    
    bool cmp(data x,data y){return x.x<y.x;}
    void update(int u,int lc,int lv){
    	sumv[u]=sumv[lc]+sumv[lv];
    	sl[u]=max(sl[lc],sumv[lc]+sl[lv]);
    	sr[u]=max(sr[lv],sumv[lv]+sr[lc]);
    }
    
    int build(int l,int r){
    	int u=++tt,mid=(l+r)>>1;
    	sumv[u]=l-r-1,sl[u]=sr[u]=-1;
    	if(l!=r){
    		le[u]=build(l,mid);
    		ri[u]=build(mid+1,r);
    	}
    	return u;
    }
    
    int add(int u,int l,int r){
    	int v=++tt,mid=(l+r)>>1;
    	le[v]=le[u];ri[v]=ri[u];
    	if(l==r) sl[v]=sr[v]=sumv[v]=1;
    	else{
    		if(L<=mid) le[v]=add(le[u],l,mid);
    		else ri[v]=add(ri[u],mid+1,r);
    		update(v,le[v],ri[v]);
    	}
    	return v;
    }
    
    void query(int u,int l,int r){
    	int mid=(l+r)>>1;
    	if(L<=l && r<=R){
    		if(!D) sumv[N]=sumv[u],sl[N]=sl[u],sr[N]=sr[u],D=1;
    		else update(N^1,N,u),N^=1; return;
    	}
    	if(L<=mid) query(le[u],l,mid);
    	if(R>mid) query(ri[u],mid+1,r);
    }
    
    bool check(int x){
    	int now=0;
    	if(q[2]-q[1]>1) pt(x,q[1]+1,q[2]-1),now+=sumv[N];
    	pt(x,q[0],q[1]); now+=sr[N];
    	pt(x,q[2],q[3]); now+=sl[N];
    	return now>=0;
    }
    
    int main(){
    	File("a");
    	n=getint();
    	for(int i=1;i<=n;i++) d[++ld]=a[i]=getint();
    	sort(d+1,d+ld+1); ld=unique(d+1,d+ld+1)-d-1;
    	for(int i=1;i<=n;i++) s[i].x=a[i]=lower_bound(d+1,d+ld+1,a[i])-d,s[i].y=i;
    	rt[ld+1]=build(1,n); sort(s+1,s+n+1,cmp);
    	for(int i=n,o;o=s[i].x,i;i--){
    		if(s[i].x!=s[i+1].x) rt[o]=rt[o+1];
    		L=R=s[i].y,rt[o]=add(rt[o],1,n);
    	}
    	m=getint(); N=MAXN-2;
    	while(m--){
    		for(int i=0;i<4;i++) q[i]=(ans+getint())%n+1;
    		sort(q,q+4); ans=0;
    		int l=1,r=ld,mid;
    		while(l!=r){
    			mid=(l+r+1)>>1;
    			if(check(mid)) l=mid;
    			else r=mid-1;
    		}
    		printf("%d
    ",ans=d[l]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Delphi的idhttp报508 Loop Detected错误的原因
    Delphi的idhttp报IOHandler value is not valid错误的原因
    华为S5700S-52P-LI-AC千兆网管交换机web登录界面配置
    解决win2003/2008下注册机或破解补丁程序无法运行问题
    SQL拆分(转)
    1602四线驱动
    ADC取样
    Delphi AES加密(转)
    使用Qt开发中国象棋(一):概述
    清除当前文件夹下.svn文件的方法
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6529000.html
Copyright © 2020-2023  润新知