洛谷P2839 [国家集训队]middle 主席树_二分
Code:
#include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> using namespace std; void setIO(string a) { string in=a+".in",out=a+".out"; freopen(in.c_str(),"r",stdin); //freopen(out.c_str(),"w",stdout); } #define maxn 210000 int arr[maxn],A[maxn],root[maxn],n; vector<int>position[maxn]; struct Segment_Tree { #define max_Tree 21000*100 int lson[max_Tree],rson[max_Tree],cnt; int sumv[max_Tree],lmax[max_Tree],rmax[max_Tree]; void pushup(int o) { sumv[o]=sumv[lson[o]]+sumv[rson[o]]; lmax[o]=max(lmax[lson[o]],sumv[lson[o]]+lmax[rson[o]]); rmax[o]=max(rmax[rson[o]],sumv[rson[o]]+rmax[lson[o]]); } void build(int l,int r,int &o) { if(l>r)return; o=++cnt; if(l==r) { sumv[o]=lmax[o]=rmax[o]=1; return; } int mid=(l+r)>>1; build(l,mid,lson[o]); build(mid+1,r,rson[o]); pushup(o); } int update(int l,int r,int o,int pos) //modify val[pos] from 1 to -1 { int oo=++cnt; int mid=(l+r)>>1; sumv[oo]=sumv[o]; lson[oo]=lson[o]; rson[oo]=rson[o]; if(l==r) { sumv[oo]=-1; lmax[oo]=rmax[oo]=0; return oo; } if(pos<=mid) lson[oo]=update(l,mid,lson[o],pos); else rson[oo]=update(mid+1,r,rson[o],pos); pushup(oo); return oo; } int query_sum(int l,int r,int o,int L,int R) { if(l>r||r<L||l>R)return 0; if(l>=L&&r<=R) return sumv[o]; int mid=(l+r)>>1; return query_sum(l,mid,lson[o],L,R)+query_sum(mid+1,r,rson[o],L,R); } int query_left(int l,int r,int o,int L,int R) { if(l>r||r<L||l>R)return 0; if(l>=L&&r<=R) return lmax[o]; int mid=(l+r)>>1; return max(query_left(l,mid,lson[o],L,R),query_sum(l,mid,lson[o],L,R)+query_left(mid+1,r,rson[o],L,R)); } int query_right(int l,int r,int o,int L,int R) { if(l>r||r<L||l>R)return 0; if(l>=L&&r<=R) return rmax[o]; int mid=(l+r)>>1; return max(query_right(mid+1,r,rson[o],L,R),query_sum(mid+1,r,rson[o],L,R)+query_right(l,mid,lson[o],L,R)); } bool check(int a,int b,int c,int d,int tps) { int sum1=query_sum(1,n,root[tps],b,c); int sum2=query_right(1,n,root[tps],a,b-1); int sum3=query_left(1,n,root[tps],c+1,d); if(sum1+sum2+sum3>=0) return true; return false; } }tree; int main() { //setIO("input"); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&arr[i]); for(int i=1;i<=n;++i) A[i]=arr[i]; sort(A+1,A+1+n); for(int i=1;i<=n;++i) arr[i]=lower_bound(A+1,A+1+n,arr[i])-A; //离散编号 for(int i=1;i<=n;++i) position[arr[i]].push_back(i); sort(arr+1,arr+1+n); int pre=arr[1]; tree.build(1,n,root[pre]); for(int i=2;i<=arr[n];++i) { int a=root[i-1]; for(int v=0;v<position[i-1].size();++v) a=tree.update(1,n,a,position[i-1][v]); root[i]=a; } int q,a,b,c,d,lastans=0,que[10]; scanf("%d",&q); while(q--) { for(int i=1;i<=4;++i) scanf("%d",&que[i]),que[i]=(que[i]+lastans)%n+1; sort(que+1,que+1+4); a=que[1],b=que[2],c=que[3],d=que[4]; int l=1,r=n,mid,ans=1; while(l<=r) { mid=(l+r)>>1; if(tree.check(a,b,c,d,mid)) l=mid+1,ans=mid; else r=mid-1; } lastans=A[ans]; printf("%d\n",lastans); } return 0; }