zoukankan      html  css  js  c++  java
  • [Data]带修改的主席树[树状数组套主席树]

      树状数组套主席树

    树状数组的每个节点维护的是一段区间,我们将每个区间构造成一棵线段树,这时候如果我们要修改一个值,只需要修改logn个节点即可,

    时间复杂度为log^2(n),树状数组维护的区间是数的个数n;离散化时是把所有数(包括要修改的数)全部离散化;

    1.修改

    在修改之前,我们应先把序列里原来的值在主席树对应节点+1(主席树里维护的是某个数出现的次数),遍历logn棵主席树。在修改时,先把该

    数原来的值的在主席树上的对应节点+(-1),再把要修改的值在对应节点+1,并在原数组上修改;

    2.查询区间K大

    其实查询和普通主席树在原理上并没有什么区别,都是用二分,然后树套树就是把一个区间的主席树拆成了若干部分,(由树状数组来完成),

    例:我们要查询区间[l,r]第k大,用一个数组来记录从1到l要经过的每棵主席树的根节点,再用另一个数组来记录从1到r要经过的每棵主席树的

    根节点,利用前缀和思想,在查询时先把第一个数组的值的sum累加起来,另一个也一样,两个数组作差,得到的就是区间l到r的数出现的个数,

    然后再用二分不断缩小范围,直至l==r;

    luogu 2617:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #define lowbit(x) x&-x
      5 using namespace std;
      6 #define maxn  10005
      7 int totn=0,cnt=0,a[maxn*2],s[maxn<<1],ls[maxn*600],rs[maxn*600],val[maxn*600],rt[maxn*600],sz=0,ca[maxn*2],cb[maxn*2],totx,toty,n,xx[maxn],yy[maxn],cc[maxn];
      8 //void build(int &p,int l,int r){
      9 //    p=++cnt;
     10 //    if(l!=r){
     11 //        int mid=(l+r)/2;
     12 //        build(ls[p],l,mid);
     13 //        build(rs[p],mid+1,r);
     14 //    }
     15 //}
     16 void insert(int &p,int cmp,int x,int l,int r,int v){
     17     p=++cnt;ls[p]=ls[cmp];rs[p]=rs[cmp];val[p]=val[cmp]+v;
     18     if(l!=r){
     19         int mid=(l+r)/2;
     20         if(x<=mid){
     21             insert(ls[p],ls[cmp],x,l,mid,v);
     22         }
     23         else{
     24             insert(rs[p],rs[cmp],x,mid+1,r,v);
     25         }
     26     }
     27 }
     28 int query(int l,int r,int k){
     29     int i;
     30     if(l==r) return l;
     31     int sum=0,mid=l+r>>1;
     32     for(int i=1;i<=totx;i++) sum-=val[ls[xx[i]]];
     33     for(int i=1;i<=toty;i++) sum+=val[ls[yy[i]]];
     34     if(k<=sum) {
     35         for(i=1;i<=totx;i++) xx[i]=ls[xx[i]];
     36         for(i=1;i<=toty;i++) yy[i]=ls[yy[i]];
     37         return query(l,mid,k);}
     38     else {
     39         for(int i=1;i<=totx;i++) xx[i]=rs[xx[i]];
     40         for(int i=1;i<=toty;i++) yy[i]=rs[yy[i]];
     41         return query(mid+1,r,k-sum); }
     42 }
     43 void add(int x,int v){
     44     int k=lower_bound(s+1,s+totn+1,a[x])-s;
     45     for(int i=x;i<=n;i+=lowbit(i)) insert(rt[i],rt[i],k,1,totn,v);
     46 }
     47 int read(){
     48     int s=0;
     49     char c;
     50     while(c<'0'||c>'9') c=getchar();
     51     while(c>='0'&&c<='9'){
     52         s=s*10+c-48;
     53         c=getchar();
     54     }
     55     return s;
     56 }
     57 int main()
     58 {
     59     int m,l,r,k,i;
     60     char ch;
     61     n=read();m=read();
     62     for(i=1;i<=n;i++){
     63         a[i]=read();
     64         s[++totn]=a[i];
     65     }
     66     for(i=1;i<=m;i++){
     67         scanf(" %c",&ch);//scanf("%d%d",&ca[i],&cb[i]);
     68         ca[i]=read();cb[i]=read();
     69         if(ch=='Q') cc[i]=read();
     70         //scanf("%d",&cc[i]);
     71         else{
     72             s[++totn]=cb[i];
     73         }
     74     }
     75     sort(s+1,s+totn+1);
     76     sz=unique(s+1,s+totn+1)-s-1;
     77     for(i=1;i<=n;i++)
     78     add(i,1);
     79 //    build(rt[0],1,sz);
     80 //    for(i=1;i<=n;i++){
     81 //        insert(rt[i],rt[i-1],lower_bound(s+1,s+sz+1,a[i])-s,1,sz);
     82 //    }
     83 //    for(i=1;i<=m;i++){
     84 //        scanf("%d%d%d",&l,&r,&k);
     85 //        printf("%d
    ",s[query(rt[l-1],rt[r],1,sz,k)]);
     86 //    }
     87     for(i=1;i<=m;i++){
     88         if(cc[i]){
     89             totx=0;
     90             toty=0;
     91             for(int j=ca[i]-1;j;j-=lowbit(j)) xx[++totx]=rt[j];
     92             for(int j=cb[i];j;j-=lowbit(j)) yy[++toty]=rt[j];
     93             printf("%d
    ",s[query(1,totn,cc[i])]);
     94         }
     95         else {
     96             add(ca[i],-1);
     97             a[ca[i]]=cb[i];
     98             add(ca[i],1);
     99         }
    100     }
    101 }
    View Code

     

  • 相关阅读:
    linux命令---常用stty的命令
    Linux命令--- /dev/null和/dev/tty
    linux---正则表达式
    linux命令---shell脚本调试
    linux命令---wc
    linux命令---head与tail
    javascrit2.0完全参考手册(第二版) 第1章第2节:javascript的历史和使用
    javascrit2.0完全参考手册(第二版) 第1章第1节 在XHTML文档中增加javascript
    (JavaScript 2.0: The Complete Reference, Second Edition)javascript 2.0完全手册第二版 翻译说明
    采用EntityFramework.Extended 对EF进行扩展
  • 原文地址:https://www.cnblogs.com/Fish-/p/8168960.html
Copyright © 2011-2022 走看看