• 高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings


    Dynamic Rankings

    Time Limit: 10 Seconds      Memory Limit: 32768 KB

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.

    Your task is to write a program for this computer, which

    - Reads N numbers from the input (1 <= N <= 50,000)

    - Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.


    Input

    The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.

    The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format

    Q i j k or
    C i t

    It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.

    There're NO breakline between two continuous test cases.


    Output

    For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])

    There're NO breakline between two continuous test cases.


    Sample Input

    2
    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3
    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3


    Sample Output

    3
    6
    3
    6

      不知道为何,ZOJ上交这道题要FQ,BZOJ上有这道题,还TM是权限题,估计是偷的(鄙视BZOJ)。

      因为有修改操作,考虑保持原有的主席树结构,假设i位置上的数变化,那么要修改主席树中i及i以后的位置,如果一个一个修改肯定超时,可以考虑将修改的时间摊到查询上去,用Bit维护修改操作,记为前缀和,很好脑补。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 using namespace std;
      6 const int maxn=60010;
      7 const int maxm=2500010;
      8 int tot,cnt,hash[maxn],a[maxn];
      9 int sum[maxm],ch[maxm][2],rt[maxn],bit[maxn];
     10 int use[maxn],n;
     11 struct Ask{
     12     int l,r,k;
     13 }q[maxn];
     14 
     15 void Insert(int pre,int &rt,int l,int r,int g,int d){
     16     rt=++cnt;
     17     ch[rt][0]=ch[pre][0];
     18     ch[rt][1]=ch[pre][1];
     19     sum[rt]=sum[pre]+d;
     20     if(l==r)return;
     21     int mid=(l+r)>>1;
     22     if(mid>=g)Insert(ch[pre][0],ch[rt][0],l,mid,g,d);
     23     else Insert(ch[pre][1],ch[rt][1],mid+1,r,g,d);
     24 }
     25 
     26 void Modify(int p,int g,int d){
     27     while(p<=n){
     28         Insert(bit[p],bit[p],1,tot,g,d);
     29         p+=p&(-p);
     30     }
     31 }
     32 
     33 int Query(int pre,int rt,int l,int r,int k,int L,int R){
     34     if(l==r)return l;
     35     int mid=(l+r)>>1,p=R,c=0;
     36     while(p){c+=sum[ch[use[p]][0]];p-=p&(-p);}p=L-1;
     37     while(p){c-=sum[ch[use[p]][0]];p-=p&(-p);}
     38     c+=sum[ch[rt][0]]-sum[ch[pre][0]];
     39     if(c>=k){
     40         p=R;
     41         while(p){use[p]=ch[use[p]][0];p-=p&(-p);}p=L-1;
     42         while(p){use[p]=ch[use[p]][0];p-=p&(-p);}
     43         return Query(ch[pre][0],ch[rt][0],l,mid,k,L,R);
     44     }
     45     else{
     46         k-=c;p=R;
     47         while(p){use[p]=ch[use[p]][1];p-=p&(-p);}p=L-1;
     48         while(p){use[p]=ch[use[p]][1];p-=p&(-p);}
     49         return Query(ch[pre][1],ch[rt][1],mid+1,r,k,L,R);
     50     }
     51     
     52 }
     53 
     54 int Solve(int l,int r,int k){
     55     int p=l-1;
     56     while(p){use[p]=bit[p];p-=p&(-p);}p=r;
     57     while(p){use[p]=bit[p];p-=p&(-p);}
     58     return Query(rt[l-1],rt[r],1,tot,k,l,r);
     59 }
     60 
     61 void Init(){
     62     memset(rt,0,sizeof(rt));cnt=0;
     63     memset(bit,0,sizeof(bit));
     64 }
     65 
     66 bool cmp(int a,int b){
     67     return a>b;
     68 }
     69 char op[5]; 
     70 int main(){
     71     int T,Q;
     72     scanf("%d",&T);
     73     while(T--){
     74         Init();
     75         scanf("%d%d",&n,&Q);
     76         for(int i=1;i<=n;i++)
     77             scanf("%d",&a[i]);
     78         tot=n;
     79         for(int i=1;i<=Q;i++){
     80             scanf("%s",op);
     81             if(op[0]=='Q')
     82                 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
     83             else{
     84                 scanf("%d%d",&q[i].l,&q[i].k);
     85                 a[++tot]=q[i].k;q[i].r=-1;
     86             }
     87         }        
     88         for(int i=1;i<=tot;i++)
     89             hash[i]=a[i];
     90         sort(hash+1,hash+tot+1);
     91         for(int i=1;i<=tot;i++)
     92             a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash;    
     93 
     94         for(int i=1;i<=n;i++)
     95             Insert(rt[i-1],rt[i],1,tot,a[i],1);
     96         for(int i=1,head=n;i<=Q;i++){
     97             if(q[i].r==-1){
     98                 Modify(q[i].l,a[q[i].l],-1);
     99                 Modify(q[i].l,a[++head],1);
    100                 a[q[i].l]=a[head];
    101             }
    102             else
    103                 printf("%d
    ",hash[Solve(q[i].l,q[i].r,q[i].k)]);
    104         }
    105     }
    106     return 0;
    107 }

    2016年6月9日重打了一遍……

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 const int maxn=60010;
     7 const int maxm=2500010;
     8 char op[10];
     9 int n,Q,T,use[maxn];
    10 int qa[maxn],qb[maxn],qk[maxn];
    11 int tot,cnt,ch[maxm][2],sum[maxm];
    12 int a[maxn],hash[maxn],bit[maxn],rt[maxn];
    13 void Insert(int pre,int &rt,int l,int r,int g,int d){
    14     rt=++cnt;
    15     ch[rt][0]=ch[pre][0];
    16     ch[rt][1]=ch[pre][1];
    17     sum[rt]=sum[pre]+d;
    18     if(l==r)return;
    19     if(l+r>>1>=g)Insert(ch[pre][0],ch[rt][0],l,l+r>>1,g,d);
    20     else Insert(ch[pre][1],ch[rt][1],(l+r>>1)+1,r,g,d);
    21 }
    22 void Modify(int p,int g,int d){
    23     while(p<=n){
    24         Insert(bit[p],bit[p],1,tot,g,d);
    25         p+=p&(-p);
    26     }
    27 }
    28 int Query(int pre,int rt,int l,int r,int k,int L,int R){
    29     if(l==r)return l;
    30     int c=sum[ch[rt][0]]-sum[ch[pre][0]],p=R;
    31     while(p){c+=sum[ch[use[p]][0]];p-=p&(-p);}p=L-1;
    32     while(p){c-=sum[ch[use[p]][0]];p-=p&(-p);}
    33     if(c>=k){p=R;
    34         while(p){use[p]=ch[use[p]][0];p-=p&(-p);}p=L-1;
    35         while(p){use[p]=ch[use[p]][0];p-=p&(-p);}
    36         return Query(ch[pre][0],ch[rt][0],l,l+r>>1,k,L,R);
    37     }
    38     else{p=R;
    39         while(p){use[p]=ch[use[p]][1];p-=p&(-p);}p=L-1;
    40         while(p){use[p]=ch[use[p]][1];p-=p&(-p);}
    41         return Query(ch[pre][1],ch[rt][1],(l+r>>1)+1,r,k-c,L,R);
    42     }
    43 }    
    44 int Solve(int i){
    45     int p=qb[i];
    46     while(p){use[p]=bit[p];p-=p&(-p);}p=qa[i]-1;
    47     while(p){use[p]=bit[p];p-=p&(-p);}
    48     return Query(rt[qa[i]-1],rt[qb[i]],1,tot,qk[i],qa[i],qb[i]);
    49 }
    50 void Init(){
    51     memset(bit,0,sizeof(bit));
    52     cnt=0;tot=n;
    53 }
    54 int main(){
    55 #ifndef ONLINE_JUDGE
    56     freopen("dynrank.in","r",stdin);
    57     freopen("dynrank.out","w",stdout);
    58 #endif
    59     scanf("%d",&T);
    60     while(T--){
    61         scanf("%d%d",&n,&Q);Init();
    62         for(int i=1;i<=n;i++){
    63             scanf("%d",&a[i]);
    64             hash[i]=a[i];
    65         }
    66         for(int i=1;i<=Q;i++){
    67             scanf("%s",op);
    68             if(op[0]=='Q')scanf("%d%d%d",&qa[i],&qb[i],&qk[i]);
    69             else{
    70                 scanf("%d%d",&qa[i],&qk[i]);
    71                 tot++;hash[tot]=a[tot]=qk[i];qb[i]=-1;
    72             }
    73         }
    74         sort(hash+1,hash+tot+1);
    75         for(int i=1;i<=tot;i++)
    76             a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash;    
    77         for(int i=1;i<=n;i++)Insert(rt[i-1],rt[i],1,tot,a[i],1);
    78         for(int i=1,p=n;i<=Q;i++){
    79             if(qb[i]==-1){
    80                 Modify(qa[i],a[qa[i]],-1);
    81                 Modify(qa[i],a[++p],1);
    82                 a[qa[i]]=a[p];
    83             }
    84             else
    85                 printf("%d
    ",hash[Solve(i)]);
    86         }
    87     }
    88     return 0;
    89 }

       还打了一个强大的整体二分。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 const int maxn=200010;
     6 int T,n,Q,cntQ;
     7 int num[maxn],ans[maxn],bit[maxn];
     8 char op[10];
     9 struct Node{
    10     int x,y,k,id,tp;
    11 }a[maxn],t1[maxn],t2[maxn];
    12 //tp==1 add; tp==2 del; tp==3 query;
    13 
    14 void Add(int x,int d){
    15     while(x<=n){
    16         bit[x]+=d;
    17         x+=x&(-x);
    18     }
    19 }
    20 
    21 int Query(int x){
    22     int ret=0;
    23     while(x){
    24         ret+=bit[x];
    25         x-=x&(-x);
    26     }
    27     return ret;
    28 }
    29 
    30 void Solve(int h,int t,int l,int r){
    31     if(l==r){
    32         for(int i=h;i<=t;i++)
    33             if(a[i].tp==3)ans[a[i].id]=l;
    34         return;
    35     }
    36     if(h>t)return;
    37     int p1=0,p2=0,d;
    38     for(int i=h;i<=t;i++){
    39         if(a[i].tp==3){
    40             d=Query(a[i].y)-Query(a[i].x-1);
    41             if(d>=a[i].k)t1[++p1]=a[i];
    42             else{
    43                 a[i].k-=d;
    44                 t2[++p2]=a[i];
    45             }
    46         }
    47         else if(a[i].k<=l+r>>1){
    48             if(a[i].tp==1)Add(a[i].x,1);
    49             if(a[i].tp==2)Add(a[i].x,-1);
    50             t1[++p1]=a[i];
    51         }
    52         else t2[++p2]=a[i];
    53     }
    54     for(int i=h;i<=t;i++){
    55         if(a[i].k<=l+r>>1){
    56             if(a[i].tp==1)Add(a[i].x,-1);
    57             if(a[i].tp==2)Add(a[i].x,1);
    58         }
    59     }
    60     for(int i=1;i<=p1;i++)a[h+i-1]=t1[i];
    61     for(int i=1;i<=p2;i++)a[h+i+p1-1]=t2[i];
    62     Solve(h,h+p1-1,l,l+r>>1);
    63     Solve(h+p1,t,(l+r>>1)+1,r);
    64 }
    65 
    66 int main(){
    67 #ifndef ONLINE_JUDGE
    68     freopen("dynrank.in","r",stdin);
    69     freopen("dynrank.out","w",stdout);
    70 #endif
    71     scanf("%d",&T);
    72     while(T--){
    73         scanf("%d%d",&n,&Q);
    74         for(int i=1;i<=n;i++){
    75             scanf("%d",&a[i].k);
    76             a[i].x=i;a[i].tp=1;
    77             num[i]=a[i].k;
    78         }
    79         cntQ=0;
    80         int x,y,k;
    81         while(Q--){
    82             scanf("%s",op);
    83             if(op[0]=='Q'){
    84                 scanf("%d%d%d",&x,&y,&k);
    85                 a[++n].id=++cntQ;a[n].tp=3;
    86                 a[n].x=x;a[n].y=y;a[n].k=k;
    87             }
    88             else{
    89                 scanf("%d%d",&x,&k);
    90                 a[++n].tp=2;a[n].x=x;a[n].k=num[x];
    91                 a[++n].tp=1;a[n].x=x;a[n].k=k;num[x]=k;
    92             }
    93         }
    94         Solve(1,n,1,1000000000);
    95         for(int i=1;i<=cntQ;i++)
    96             printf("%d
    ",ans[i]);            
    97     }
    98     return 0;    
    99 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    《移动开发者周刊》第十一期
    2012安卓巴士开发者沙龙成都站大家抓紧报名
    23岁那年你正处在哪个状态?现在呢?
    《老罗Android开发视频教程》老罗来交国庆的答卷了
    程序员,你的一千万在哪里?
    《老罗Android开发视频教程》更新
    2012全球开发者大会项目投资一对一相亲会
    windows远程桌面
    [LeetCode] NQueens
    [LeetCode] Pascal's Triangle II
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5375289.html
Copyright © 2020-2023  润新知