zoukankan      html  css  js  c++  java
  • 【BOZJ 1901】Zju2112 Dynamic Rankings

    Description

    给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

    Input

    对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

    Output

     

    Sample Input

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

    Sample Output

    3
    6

    HINT

    20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

     
    树套树
      1 #include<cstdio>
      2 #include<cstdlib>
      3 using namespace std;
      4 const int N=3000001,inf=1000000000;
      5 struct tree{int lch,rch,num,sz,w,rnd;}tr[N];
      6 int a[10010],n,m,sz,root[10010*4];
      7 void updata(int x){
      8     int l=tr[x].lch,r=tr[x].rch;
      9     tr[x].sz=tr[l].sz+tr[r].sz+tr[x].w;
     10 }
     11  
     12 void lturn(int &k)
     13 {int t=tr[k].rch;tr[k].rch=tr[t].lch;tr[t].lch=k;updata(k);updata(t);k=t;}
     14 void rturn(int &k)
     15 {int t=tr[k].lch;tr[k].lch=tr[t].rch;tr[t].rch=k;updata(k);updata(t);k=t;}
     16 void ins(int &k,int x){
     17     if(!k){
     18         k=++sz;tr[k].rnd=rand();tr[k].sz=1;tr[k].num=x;tr[k].w=1;return;
     19     }
     20     if(tr[k].num==x) tr[k].w++;
     21     else if(tr[k].num>x) {
     22         ins(tr[k].lch,x);
     23         if(tr[k].rnd>tr[tr[k].lch].rnd) rturn(k);
     24     }else{
     25         ins(tr[k].rch,x);
     26         if(tr[k].rnd>tr[tr[k].rch].rnd) lturn(k);
     27     }
     28     updata(k);
     29 }
     30  
     31 void insert(int k,int l,int r,int x,int y){
     32     if(l<=y&&r>=y) ins(root[k],x);
     33     if(l==r) return;
     34     int mid=(l+r)>>1;
     35     if(y>mid) insert(k<<1|1,mid+1,r,x,y);
     36     else insert(k<<1,l,mid,x,y);
     37 }
     38  
     39 int find(int k,int x){
     40     if(!k) return 0;
     41     int l=tr[k].lch,r=tr[k].rch;
     42     if(tr[k].num>x) return find(l,x);
     43     else if(tr[k].num<x) return find(r,x)+tr[l].sz+tr[k].w;
     44     else return tr[l].sz;
     45 }
     46  
     47 int get_rank(int k,int l,int r,int L,int R,int x){
     48     int mid=(l+r)>>1;
     49     if(l==L&&r==R) return find(root[k],x);
     50     if(R<=mid) return get_rank(k<<1,l,mid,L,R,x);
     51     else if(L>mid) return get_rank(k<<1|1,mid+1,r,L,R,x);
     52     else return get_rank(k<<1,l,mid,L,mid,x)+get_rank(k<<1|1,mid+1,r,mid+1,R,x);
     53 }
     54  
     55 int ask(int x,int y,int rk){
     56     int l=1,r=inf,mid=(l+r)>>1,ans=0;
     57     while(l<=r){
     58         mid=(l+r)>>1;
     59         int k=get_rank(1,1,n,x,y,mid);
     60         if(k<=rk) ans=mid,l=mid+1;
     61         else r=mid-1;
     62     }
     63     return ans;
     64 }
     65  
     66 void del(int &k,int p){
     67     if(tr[k].num==p){
     68         if(tr[k].w>1) tr[k].w--,tr[k].sz--;
     69         else{
     70             if(tr[k].lch*tr[k].rch==0) k=tr[k].lch+tr[k].rch;
     71             else if(tr[tr[k].lch].rnd<tr[tr[k].rch].rnd) rturn(k),del(k,p);
     72             else lturn(k),del(k,p);
     73         }
     74     }
     75     else{
     76         tr[k].sz--;
     77         if(tr[k].num>p) del(tr[k].lch,p);else del(tr[k].rch,p);
     78     }
     79 }
     80  
     81 void make(int &rt,int p,int t){
     82     ins(rt,t);
     83     del(rt,p);
     84 }
     85  
     86 void change(int k,int l,int r,int x,int p,int t){
     87     if(l<=x&&r>=x) make(root[k],p,t);
     88     if(l==r) return;
     89     int mid=(l+r)>>1;
     90     if(x<=mid) change(k<<1,l,mid,x,p,t);
     91     else change(k<<1|1,mid+1,r,x,p,t);
     92 }
     93  
     94 int main(){
     95     scanf("%d%d",&n,&m);
     96     for(int i=1;i<=n;i++){
     97         scanf("%d",&a[i]);
     98         insert(1,1,n,a[i],i);
     99     }
    100     char s[4];
    101     for(int i=1;i<=m;i++){
    102         scanf("%s",s);
    103         if(s[0]=='Q') {
    104             int l,r,rk;
    105             scanf("%d%d%d",&l,&r,&rk);
    106             printf("%d
    ",ask(l,r,rk-1));
    107         }else{
    108             int x,t;
    109             scanf("%d%d",&x,&t);
    110             change(1,1,n,x,a[x],t);
    111             a[x]=t;
    112         }
    113     }
    114 }

    树状数组+主席树

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define N 2200001
     5 using namespace std;
     6 int n,m,tot,top,cnt;
     7 int v[10001],num[20001];
     8 int A[10001],B[10001],X[10001],root[10001],K[10001];
     9 int sz[N],ls[N],rs[N];
    10 int L[30],R[30],a,b;
    11 int lowbit(int x){return x&(-x);}
    12 void updata(int last,int l,int r,int &k,int x,int add){
    13     k=++cnt;
    14     int mid=(l+r)>>1;
    15     sz[k]=sz[last]+add;ls[k]=ls[last];rs[k]=rs[last];
    16     if(l==r) return;
    17     if(x<=mid) updata(ls[last],l,mid,ls[k],x,add);
    18     else updata(rs[last],mid+1,r,rs[k],x,add);
    19 }
    20  
    21 int query(int l,int r,int k){
    22     if(l==r) return l;
    23     int mid=(l+r)>>1;
    24     int suml=0,sumr=0;
    25     for(int i=1;i<=a;i++)suml+=sz[ls[L[i]]];
    26     for(int i=1;i<=b;i++)sumr+=sz[ls[R[i]]];
    27     if(sumr-suml>=k){
    28         for(int i=1;i<=a;i++) L[i]=ls[L[i]];
    29         for(int i=1;i<=b;i++) R[i]=ls[R[i]];
    30         return query(l,mid,k);
    31     }else{
    32         for(int i=1;i<=a;i++) L[i]=rs[L[i]];
    33         for(int i=1;i<=b;i++) R[i]=rs[R[i]];
    34         return query(mid+1,r,k-(sumr-suml));
    35     }
    36 }
    37  
    38 int main(){
    39     scanf("%d%d",&n,&m);
    40     for(int i=1;i<=n;i++){
    41         scanf("%d",&v[i]);
    42         num[++top]=v[i];
    43     }
    44     char opt[4];
    45     for(int i=1;i<=m;i++){
    46         scanf("%s%d%d",opt,&A[i],&B[i]);
    47         if(opt[0]=='Q') scanf("%d",&X[i]),K[i]=1;
    48         else num[++top]=B[i];
    49     }
    50     sort(num+1,num+top+1);
    51     tot=unique(num+1,num+top+1)-num-1;
    52     for(int i=1;i<=n;i++){
    53         int t=lower_bound(num+1,num+tot+1,v[i])-num;
    54         for(int j=i;j<=n;j+=lowbit(j))
    55             updata(root[j],1,tot,root[j],t,1);
    56     }
    57     for(int i=1;i<=m;i++){
    58         if(K[i]){
    59             a=0,b=0;A[i]--;
    60             for(int j=A[i];j>=1;j-=lowbit(j)) L[++a]=root[j];
    61             for(int j=B[i];j>=1;j-=lowbit(j)) R[++b]=root[j];
    62             printf("%d
    ",num[query(1,tot,X[i])]);
    63         }else{
    64             int t=lower_bound(num+1,num+tot+1,v[A[i]])-num;
    65             for(int j=A[i];j<=n;j+=lowbit(j)) 
    66             updata(root[j],1,tot,root[j],t,-1);
    67             v[A[i]]=B[i];
    68             t=lower_bound(num+1,num+tot+1,v[A[i]])-num;
    69             for(int j=A[i];j<=n;j+=lowbit(j)) 
    70             updata(root[j],1,tot,root[j],t,1);
    71         }
    72     }
    73 }

    整体二分

     1 #include<cstdio>
     2 const int inf=1000000000;
     3 struct node{int flag,x,y,no,rk,cur;}p[300100],p1[300100],p2[300010];
     4 int n,m,a[100010],cnt,sum,ans[100100],w[300010],tmp[300010],num;
     5  
     6 void add(int x,int y){
     7     for(int i=x;i<=n;i+=(i&(-i))) w[i]+=y; 
     8 } 
     9  
    10 int query(int x){
    11     int ans=0;
    12     for (int i=x;i>0;i-=(i&(-i))) ans+=w[i];
    13     return ans;
    14 }
    15  
    16 void divid(int h,int t,int l,int r){
    17     if(h>t) return;
    18     if(l==r) {for(int i=h;i<=t;i++) 
    19             ans[p[i].no]=l;return;} 
    20     int mid=(l+r)>>1;
    21     for(int i=h;i<=t;i++){
    22         if(p[i].flag==1&&p[i].y<=mid) add(p[i].x,1);
    23         else if(p[i].flag==2&&p[i].y<=mid) add(p[i].x,-1);
    24         else if(p[i].flag==3)tmp[i]=query(p[i].y)-query(p[i].x-1);
    25     }
    26     for(int i=h;i<=t;i++){
    27         if(p[i].flag==1&&p[i].y<=mid) add(p[i].x,-1);
    28         else if(p[i].flag==2&&p[i].y<=mid) add(p[i].x,1);
    29     }
    30     int l1=0,l2=0;
    31     for(int i=h;i<=t;i++){
    32         if(p[i].flag==3){
    33             if(tmp[i]+p[i].cur>p[i].rk-1) p1[++l1]=p[i];
    34             else p[i].cur+=tmp[i],p2[++l2]=p[i];
    35         }
    36         else {
    37             if(p[i].y<=mid) p1[++l1]=p[i];else p2[++l2]=p[i];
    38         }
    39     }
    40     for(int i=h;i<=l1+h-1;i++) p[i]=p1[i-h+1];
    41     for(int i=l1+h;i<=t;i++) p[i]=p2[i-l1-h+1];
    42     divid(h,l1+h-1,l,mid);
    43     divid(l1+h,t,mid+1,r);
    44 }
    45  
    46 int main(){
    47     scanf("%d%d",&n,&m);
    48     for(int i=1;i<=n;i++){
    49         scanf("%d",&a[i]);
    50         p[++cnt].flag=1;p[cnt].x=i;p[cnt].y=a[i];
    51     }
    52     for(int i=1;i<=m;i++){
    53         char opt[4];int x,y,k;
    54         scanf("%s%d%d",opt,&x,&y);
    55         if(opt[0]=='Q'){
    56             scanf("%d",&k);
    57             p[++cnt].x=x,p[cnt].y=y;p[cnt].flag=3;p[cnt].no=++num;
    58             p[cnt].rk=k;
    59         }else{
    60             p[++cnt].x=x;p[cnt].y=a[x];p[cnt].flag=2;
    61             a[x]=y;
    62             p[++cnt].x=x;p[cnt].y=a[x];p[cnt].flag=1;
    63         }
    64     }
    65     divid(1,cnt,0,inf);
    66     for(int i=1;i<=num;i++) printf("%d
    ",ans[i]);
    67 } 

    这就是时间差距。。。

  • 相关阅读:
    开始学习编写用于 Windows SideShow 设备的小工具【转】
    Windows Mobile 6.5 Developer Tool Kit 下载
    Microsoft Security Essentials 微软免费杀毒软件下载
    SQL Server 2008 空间数据存储摘抄(SRID 点 MultiPoint LineString MultiLineString 多边形 MultiPolygon GeometryCollection)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (2)
    Vista Sidebar Gadget (侧边栏小工具)开发教程 (4)
    负载测试、压力测试和性能测试的异同
    Windows Server 2008 Vista Sidebar Gadget (侧边栏小工具) 入门开发实例
    Silverlight Tools 安装失败 解决办法
    SQL Server 2008 空间数据库 空间索引概念及创建(取自帮助)
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5229600.html
Copyright © 2011-2022 走看看