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 }
View Code

 

posted @ 2017-05-04 22:22  CHADLZX  阅读(143)  评论(0编辑  收藏  举报