zoukankan      html  css  js  c++  java
  • 【bzoj2653】【middle】【主席树+二分答案】

    Description

    一个长度为 n 的序列 a ,设其排过序之后为 b ,其中位数定义为 b[n/2] ,其中 a,b 从 0 开始标号 , 除法取下整。 
    给你一个长度为 n 的序列 s 。回答 Q 个这样的询问 : s 的左端点在 [a,b] 之间 , 右端点在 [c,d] 之间的子序列中 ,最大的中位数。 
    其中 a

    Solution

    对着题解理解了半天……又对着代码调了半天……最后发现竟然是一个函数名没写orz

    不过不得不说这题真的是主席树好题

    先考虑二分答案,找出区间内比mid小的数有多少

    因为对答案的贡献只有有或没有,所以可以把比mid小的都设为-1,比mid大的都设为1,如果区间内的和大于等于0,说明mid可行,继续二分下去

    然而如果离散之后对每一个值建树,空间毫无疑问爆炸

    于是只要用主席树维护一下就可以了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 inline int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 char obuf[1<<24],*o=obuf;
    19 inline void print(int x){
    20     if(x>9) print(x/10);
    21     *o++=x%10+48;
    22 }
    23 const int N=20005,M=N*30;
    24 int n,Pre,q,cnt;
    25 int rt[N],p[5];
    26 struct node{
    27     int l,r,lmx,rmx,sum;
    28 }t[M],op;
    29 struct data{
    30     int x,id;
    31     inline bool operator <(const data &b)const
    32     {return x<b.x;}
    33 }a[N];
    34 inline void pushup(int x){
    35     t[x].sum=t[t[x].l].sum+t[t[x].r].sum;
    36     t[x].lmx=max(t[t[x].l].lmx,t[t[x].l].sum+t[t[x].r].lmx);
    37     t[x].rmx=max(t[t[x].r].rmx,t[t[x].r].sum+t[t[x].l].rmx);
    38 }
    39 void build(int &now,int l,int r){
    40     now=++cnt;
    41     if(l==r){t[now].lmx=t[now].rmx=t[now].sum=1;return;}
    42     int mid=(l+r)>>1;
    43     build(t[now].l,l,mid);
    44     build(t[now].r,mid+1,r);
    45     pushup(now);
    46 }
    47 void update(int last,int &now,int l,int r,int k){
    48     now=++cnt;
    49     if(l==r){t[now].lmx=t[now].rmx=t[now].sum=-1;return;}
    50     int mid=(l+r)>>1;
    51     if(k<=mid) t[now].r=t[last].r,update(t[last].l,t[now].l,l,mid,k);
    52     else t[now].l=t[last].l,update(t[last].r,t[now].r,mid+1,r,k);
    53     pushup(now);
    54 }
    55 node merge(node x,node y){
    56     node z;
    57     z.sum=x.sum+y.sum;
    58     z.lmx=max(x.lmx,x.sum+y.lmx);
    59     z.rmx=max(y.rmx,y.sum+x.rmx);
    60     return z;
    61 }
    62 node find(int x,int l,int r,int y,int z){
    63     if(y>z) return op;
    64     if(l==y&&r==z) return t[x];
    65     int mid=(l+r)>>1;
    66     if(z<=mid) return find(t[x].l,l,mid,y,z);
    67     else if(y>mid) return find(t[x].r,mid+1,r,y,z);
    68     else return merge(find(t[x].l,l,mid,y,mid),find(t[x].r,mid+1,r,mid+1,z));
    69 }
    70 int query(int x){
    71     return find(rt[x],1,n,p[1],p[2]).rmx+find(rt[x],1,n,p[2]+1,p[3]-1).sum+find(rt[x],1,n,p[3],p[4]).lmx;
    72 }
    73 int main(){
    74     //freopen("testdata.in","r",stdin);
    75     n=read();
    76     for(int i=1;i<=n;++i) a[i].x=read(),a[i].id=i;
    77     sort(a+1,a+1+n);
    78     build(rt[1],1,n);
    79     for(int i=2;i<=n;++i) update(rt[i-1],rt[i],1,n,a[i-1].id);
    80     q=read();
    81     while(q--){
    82         int x=read(),y=read(),z=read(),k=read();
    83         p[1]=(x+Pre)%n+1,p[2]=(y+Pre)%n+1,p[3]=(z+Pre)%n+1,p[4]=(k+Pre)%n+1;
    84         sort(p+1,p+5);
    85         int l=1,r=n,ans=1;
    86         while(l<=r){
    87             int mid=(l+r)>>1;
    88             int f=query(mid);
    89             if(f>=0) ans=mid,l=mid+1;
    90             else r=mid-1;
    91         }
    92         Pre=a[ans].x;
    93         print(a[ans].x),*o++='
    ';
    94     }
    95     fwrite(obuf,o-obuf,1,stdout);
    96     return 0;
    97 }
  • 相关阅读:
    相机中白平衡的算法模拟实现
    双边滤波算法的简易实现bilateralFilter
    图像处理卷积算法实现
    最快的3x3中值模糊
    黑米手机抢购软件通杀破解补丁
    分享一款12306购票软件
    快速堆栈模糊算法
    大数据(1)---大数据及HDFS简述
    springboot自动装配(3)---条件注解@Conditional
    随机瓜分百万红包
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9406034.html
Copyright © 2011-2022 走看看