[BZOJ2653][国家集训队]middle(主席树+二分)

xiaoxiao2021-02-28  9

题目:

我是超链接

题解:

代码:

#include <cstdio> #include <iostream> #include <algorithm> #define INF 1e9 using namespace std; const int N=25005; int n,sz,root[N],q[5],A[N],pos[N]; struct po{int z,id;}b[N]; struct hh{int lmax,rmax,sum,l,r;}tree[N*100],Ans; int cmp(po a,po b){return a.z<b.z;} void updata(int now) { int l=tree[now].l,r=tree[now].r; tree[now].lmax=max(tree[l].lmax,tree[l].sum+tree[r].lmax); tree[now].rmax=max(tree[r].rmax,tree[r].sum+tree[l].rmax); tree[now].sum=tree[l].sum+tree[r].sum; } void build(int &now,int l,int r,int x) { tree[++sz]=tree[now]; now=sz; if (l==r) {tree[now].lmax=-1; tree[now].rmax=-1; tree[now].sum=-1;return;} int mid=(l+r)>>1; if (x<=mid) build(tree[now].l,l,mid,x); else build(tree[now].r,mid+1,r,x); updata(now); } void cover(int &now,int l,int r) { tree[++sz]=tree[now]; now=sz; tree[now].lmax=tree[now].rmax=tree[now].sum=r-l+1; if (l==r) return; int mid=(l+r)>>1; cover(tree[now].l,l,mid); cover(tree[now].r,mid+1,r); updata(now); } hh merge(hh a,hh b) { hh c; c.lmax=max(a.lmax,a.sum+b.lmax); c.rmax=max(b.rmax,b.sum+a.rmax); c.sum=a.sum+b.sum; return c; } void ask(int now,int l,int r,int lrange,int rrange) { if (lrange<=l && rrange>=r){Ans=merge(Ans,tree[now]);return;} int mid=(l+r)>>1; if (lrange<=mid) ask(tree[now].l,l,mid,lrange,rrange); if (rrange>mid) ask(tree[now].r,mid+1,r,lrange,rrange); } bool work(int now,int a,int b,int c,int d) { int sb=0; Ans.lmax=-INF;Ans.rmax=-INF;Ans.sum=0; ask(root[now],1,n,c,d); sb+=Ans.lmax; Ans.lmax=-INF;Ans.rmax=-INF;Ans.sum=0; ask(root[now],1,n,a,b); sb+=Ans.rmax; Ans.lmax=-INF;Ans.rmax=-INF;Ans.sum=0; ask(root[now],1,n,b+1,c-1); sb+=Ans.sum; return sb>=0; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&b[i].z),b[i].id=i,A[i]=b[i].z; sort(b+1,b+n+1,cmp); cover(root[1],1,n); for (int i=2;i<=n;i++) root[i]=root[i-1],build(root[i],1,n,b[i-1].id); for (int i=1;i<=n;i++) pos[i]=b[i].z; int ans=0,Q; scanf("%d",&Q); while (Q--) { int a,b,c,d;scanf("%d%d%d%d",&q[1],&q[2],&q[3],&q[4]); q[1]=(ans+q[1])%n;q[2]=(ans+q[2])%n;q[3]=(ans+q[3])%n;q[4]=(ans+q[4])%n; sort(q+1,q+4+1); a=q[1]; b=q[2]; c=q[3]; d=q[4]; a++;b++;c++;d++; int l=1,r=n; while (l<=r) { int mid=(l+r)>>1; if (work(mid,a,b,c,d)) l=mid+1; else r=mid-1; } ans=pos[r]; printf("%d\n",ans); } }
转载请注明原文地址: https://www.6miu.com/read-2100135.html

最新回复(0)