• P2617 Dynamic Rankings(主席树+树状数组)


    怕是还没有题解,所以先写一篇。

    这题就是维护带修改的主席树。首先树套树肯定是能做的,既然树套树能做那么整体二分肯定也是可以的。

    由于我并没有使用这两种做法,所以此处不予介绍。

    大概描述下主席树的思路:

    首先说说怎么搞带修改主席树?

    回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth。

    那么我们如何支持修改操作?

    考虑到我们之前使用主席树朴素的维护区间前缀和,支持修改的话,只要把前缀和交给擅长它的树状数组维护,主席树只要维护下位置就好。




     1 #include"bits/stdc++.h"
     2 using namespace std;
     3 #define nn 40000000
     4 #define lowbit(x) ((x)&(-x))
     5 
     6 int rt[nn],b[nn],a[nn],ca[nn],cb[nn],cc[nn] ;  
     7 int size[nn],xx[nn],yy[nn],l[nn],r[nn];
     8 int n,m;
     9 int totn;
    10 int tot,totx,toty;
    11 
    12 inline int read(){
    13     int f=1,x=0;char ch;
    14     do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    15     do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    16     return f*x;
    17 }
    18 
    19 
    20 void change(int &y,int x,int L,int R,int pos,int v)
    21 {
    22       y=++tot; size[tot]=size[x]+v,l[tot]=l[x],r[tot]=r[x];
    23     if (L==R)return ;
    24     int mid = R+L>>1;if (pos<=mid)change(l[tot],l[x],L,mid,pos,v);
    25     else change(r[tot],r[x],mid+1,R,pos,v);
    26 }
    27 
    28 inline void add(int x,int v)
    29 {
    30     int k = lower_bound(b+1,b+1+totn,a[x])-b;
    31     for (int i=x;i<=n;i+=lowbit(i)) change(rt[i],rt[i],1,totn,k,v);
    32 }
    33 
    34 int query(int L,int R,int p)
    35 {
    36     if (L==R)return R; int sum=0; int mid = L+R>>1;
    37     for (int i=1;i<=totx;i++)sum-=size[l[xx[i]]];
    38     for (int i=1;i<=toty;i++)sum+=size[l[yy[i]]];
    39     if (p<=sum)
    40     {
    41        for ( int i=1;i<=totx;i++)xx[i]=l[xx[i]];
    42        for ( int i=1;i<=toty;i++)yy[i]=l[yy[i]];
    43        return query(L,mid,p);
    44     }
    45      for ( int i=1;i<=totx;i++)xx[i]=r[xx[i]];
    46        for ( int i=1;i<=toty;i++)yy[i]=r[yy[i]];
    47       return query(mid+1,R,p-sum);
    48 }
    49 
    50 int main()
    51 {  char s;
    52     n=read(),m=read();
    53     for (int i=1;i<=n;i++)a[i]=read(),b[++totn]=a[i];
    54 
    55     for (int i=1;i<=m;i++) 
    56     {
    57         cin>>s; if (s=='Q') ca[i]=read(),cb[i]=read(),cc[i]=read();
    58         else ca[i]=read(),cb[i]=read(),b[++totn]=cb[i];
    59     }
    60         sort(b+1,b+1+totn);
    61     totn=unique(b+1,b+1+totn)-b-1;
    62     
    63     for ( int i=1;i<=n;i++) add(i,1); 
    64     for ( int i=1;i<=m;i++)
    65     {
    66         if (cc[i]) 
    67         {  totx=toty=0;
    68             for ( int j=ca[i]-1;j;j-=lowbit(j))xx[++totx]=rt[j];
    69             for ( int j=cb[i];j;j-=lowbit(j))yy[++toty]=rt[j];
    70             printf("%d
    ",b[query(1,totn,cc[i])]);
    71         }
    72         else 
    73         {
    74             add(ca[i],-1),a[ca[i]]=cb[i],add(ca[i],1);
    75         }
    76     }
    77     
    78 }
  • 相关阅读:
    Thumbnailator压缩图片
    dubbo序列化的一点注意
    Java编程思想读书笔记之内部类
    Hello World
    sql中where和having的区别
    Linux下服务器搭建
    maven中profile的激活方式
    <![CDATA[ ]]>
    linux下用xampp安装php集成环境,并修改各自端口号
    关于星号(**/*.java)
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10294155.html
Copyright © 2020-2023  润新知