BZOJ 2653 middle
《做人要有梦想系列》
题解:
强制在线多组询问求开端在[a,b],结束在[c,d]的子序列的最大中位数。
若有两个中位数取最大的中位数。
1.如何处理中位数最大的限制?
答:二分答案,将大于等于x的数设为1,将小于x的数设为-1,[b,c]的一定要,[a,b)要rmax,(c,d]要lmax即可.
2.如何快速求上述东西?
答:开一个按权值大小排序的区间为值的主席树,然后在上面记录lmax,rmax即可.
时间:O(nlog2n) 空间:O(nlogn)。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define ll long long 5 #define FILE "dealing" 6 #define up(i,j,n) for(int i=j;i<=n;i++) 7 #define db long double 8 #define pii pair<int,int> 9 #define pb push_back 10 #define mem(a,L) memset(a,0,sizeof(int)*(L+1)) 11 template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;} 12 template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;} 13 template<class T> inline T squ(T a){return a*a;} 14 const ll maxn=2000100+10,MAXN=200200,inf=1e9+10,limit=1e7,base=23; 15 int read(){ 16 int x=0,f=1,ch=getchar(); 17 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 18 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 19 return x*f; 20 } 21 int n,Q; 22 int v[MAXN]; 23 int q[4]; 24 pii t[MAXN]; 25 int cnt,c[maxn][2],root[maxn]; 26 struct node{ 27 int lmax,rmax,sum; 28 node(int lmax=0,int rmax=0,int sum=0):lmax(lmax),rmax(rmax),sum(sum){} 29 }a[maxn]; 30 node updata(node le,node ri){ 31 node k; 32 k.lmax=max(le.lmax,le.sum+ri.lmax); 33 k.rmax=max(ri.rmax,ri.sum+le.rmax); 34 k.sum=le.sum+ri.sum; 35 return k; 36 } 37 38 void insert(int pre,int& o,int l,int r,int key){ 39 o=++cnt; 40 if(l==r){ 41 a[o].lmax=a[o].rmax=a[o].sum=1; 42 return; 43 } 44 int mid=(l+r)>>1; 45 if(key>mid)c[o][0]=c[pre][0],insert(c[pre][1],c[o][1],mid+1,r,key); 46 else c[o][1]=c[pre][1],insert(c[pre][0],c[o][0],l,mid,key); 47 if(c[o][0]&&c[o][1])a[o]=updata(a[c[o][0]],a[c[o][1]]); 48 else if(!c[o][0]&&c[o][1])a[o]=updata(node(0,0,-(mid-l+1)),a[c[o][1]]); 49 else a[o]=updata(a[c[o][0]],node(0,0,-(r-mid))); 50 } 51 node query(int o,int l,int r,int L,int R){ 52 if(l>R||r<L)return node(0,0,0); 53 if(!o)return node(0,0,-(min(r,R)-max(L,l)+1)); 54 if(l>=L&&r<=R)return a[o]; 55 int mid=(l+r)>>1; 56 return updata(query(c[o][0],l,mid,L,R),query(c[o][1],mid+1,r,L,R)); 57 } 58 bool cmp(const pii& a,const pii& b){return a.first>b.first;} 59 int main(){ 60 freopen(FILE".in","r",stdin); 61 freopen(FILE".out","w",stdout); 62 n=read(); 63 up(i,1,n)v[i]=read(),t[i].first=v[i],t[i].second=i; 64 sort(t+1,t+n+1,cmp); 65 up(i,1,n)insert(root[i-1],root[i],1,n,t[i].second); 66 Q=read();int lastans=0; 67 up(i,1,Q){ 68 up(j,0,3)q[j]=(read()+lastans)%n; 69 sort(q,q+4); 70 up(j,0,3)q[j]++; 71 int left=1,right=n,ans=0; 72 while(left<=right){ 73 int mid=(left+right)>>1; 74 node k=query(root[mid],1,n,q[1],q[2]); 75 node le=query(root[mid],1,n,q[0],q[1]-1); 76 node ri=query(root[mid],1,n,q[2]+1,q[3]); 77 int sum=k.sum+le.rmax+ri.lmax; 78 if(sum>=0)right=mid-1,ans=mid; 79 else left=mid+1; 80 } 81 printf("%d\n",lastans=t[ans].first); 82 } 83 return 0; 84 }