zoukankan      html  css  js  c++  java
  • [可持久化线段树][主席树]小结

    前言

    今天机房莫名掀起了一股学习主席树的浪潮,然而这对于早几天接触主席树的我,岂不是个XXX的好机会= =

    然而我是一个正直的人,所以就把这些鬼东西扔出来,顺便给自己做个小结

    静态主席树

    顾名思义,就是静态的,不带修改的主席树

    很简单的东西,用前缀和维护的,可以查询区间$k$小值的数据结构,然而只有理解了,才可以灵活运用,乃至将其作用推广

    懒得写教程了(其实只是不想码字= =)(那不还是懒吗)

    [HDU 2665]Kth number

    当时太年轻,打的太丑= =

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 //#define mem(x) memset((x),0,sizeof(x))
     7 inline int read(){
     8     int sum(0);
     9     char ch(getchar());
    10     for(;ch<'0'||ch>'9';ch=getchar());
    11     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
    12     return sum;
    13 }
    14 int T;
    15 int n,m;
    16 int a[100005],num[100005];
    17 int cnt,size;
    18 int rt[2000005],sum[2000005],lch[2000005],rch[2000005];
    19 inline void clear(){
    20 //    mem(a),mem(num),mem(rt),mem(sum),mem(lch),mem(rch);
    21     cnt=size=n=m=0;
    22 }
    23 inline void build(int &x,int l,int r){
    24     x=++cnt;
    25     sum[x]=0;
    26     if(l==r){
    27         lch[x]=rch[x]=0;
    28         return;
    29     }
    30     int mid((l+r)>>1);
    31     build(lch[x],l,mid);
    32     build(rch[x],mid+1,r);
    33 }
    34 inline void update(int &x,int las,int pos,int l,int r){
    35     x=++cnt;
    36     lch[x]=lch[las];
    37     rch[x]=rch[las];
    38     sum[x]=sum[las]+1;
    39     if(l==r)
    40         return;
    41     int mid((l+r)>>1);
    42     if(pos<=mid)
    43         update(lch[x],lch[las],pos,l,mid);
    44     else
    45         update(rch[x],rch[las],pos,mid+1,r);
    46 }
    47 inline int query(int ll,int rr,int l,int r,int k){
    48     if(l==r)
    49         return l;
    50     int mid((l+r)>>1);
    51     int cnt(sum[lch[rr]]-sum[lch[ll]]);
    52     if(k<=cnt)
    53         return query(lch[ll],lch[rr],l,mid,k);
    54     return query(rch[ll],rch[rr],mid+1,r,k-cnt);
    55 }
    56 int main(){
    57     T=read();
    58     while(T--){
    59         clear();
    60         n=read(),m=read();
    61         for(int i=1;i<=n;++i)
    62             num[i]=a[i]=read();
    63         sort(num+1,num+n+1);
    64         size=unique(num+1,num+n+1)-num-1;
    65         for(int i=1;i<=n;++i)
    66             a[i]=lower_bound(num+1,num+size+1,a[i])-num;
    67         build(rt[0],1,size);
    68         for(int i=1;i<=n;++i)
    69             update(rt[i],rt[i-1],a[i],1,size);
    70         for(int i=1;i<=m;++i){
    71             int l(read()),r(read()),k(read());
    72             int ans(query(rt[l-1],rt[r],1,size,k));
    73             printf("%d
    ",num[ans]);
    74         }
    75     }
    76 }
    Kth

    [Spoj 10628]Count on a tree

    树上建主席树,二分查即可

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 using namespace std;
      6 inline int read(){
      7     int sum(0);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar());
     10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     11     return sum;
     12 }
     13 struct edge{
     14     int e;
     15     edge *n;
     16 }a[200005],*pre[100005];
     17 int tot;
     18 inline void insert(int s,int e){
     19     a[++tot].e=e;
     20     a[tot].n=pre[s];
     21     pre[s]=&a[tot];
     22 }
     23 int timee;
     24 int dep[100005],fa[100005][20],l[100005],r[100005],pos[100005];
     25 int n,m;
     26 int cnt,size;
     27 int v[100005],num[100005];
     28 int rt[100005],lch[2000005],rch[2000005],sum[2000005];
     29 inline void dfs(int u){
     30     l[u]=++timee;
     31     pos[timee]=u;
     32     for(int i=1;(1<<i)<=dep[u];++i)
     33         fa[u][i]=fa[fa[u][i-1]][i-1];
     34     for(edge *i=pre[u];i;i=i->n){
     35         int e(i->e);
     36         if(e!=fa[u][0]){
     37             fa[e][0]=u;
     38             dep[e]=dep[u]+1;
     39             dfs(e);
     40         }
     41     }
     42     r[u]=timee;
     43 }
     44 inline int lca(int x,int y){
     45     if(dep[x]<dep[y])
     46         swap(x,y);
     47     int delta(dep[x]-dep[y]);
     48     for(int i=0;delta>0;++i)
     49         if(delta&(1<<i)){
     50             delta^=1<<i;
     51             x=fa[x][i];
     52         }
     53     if(x==y)
     54         return x;
     55     for(int i=19;i>=0;--i)
     56         if(fa[x][i]!=fa[y][i])
     57             x=fa[x][i],y=fa[y][i];
     58     return fa[x][0];
     59 }
     60 inline void build(int &x,int l,int r){
     61     x=++cnt;
     62     sum[x]=0;
     63     if(l==r)
     64         return;
     65     int mid((l+r)>>1);
     66     build(lch[x],l,mid);
     67     build(rch[x],mid+1,r);
     68 }
     69 inline void update(int &x,int las,int pos,int l,int r){
     70     x=++cnt;
     71     lch[x]=lch[las];
     72     rch[x]=rch[las];
     73     sum[x]=sum[las]+1;
     74     if(l==r)
     75         return;
     76     int mid((l+r)>>1);
     77     if(pos<=mid)
     78         update(lch[x],lch[las],pos,l,mid);
     79     else
     80         update(rch[x],rch[las],pos,mid+1,r);
     81 }
     82 inline int query(int x,int y,int k){
     83     int a(x),b(y),c(lca(x,y)),d(fa[c][0]);
     84     a=rt[l[a]],b=rt[l[b]],c=rt[l[c]],d=rt[l[d]];
     85     int l(1),r(size);
     86     while(l<r){
     87         int mid((l+r)>>1);
     88         int tmp(sum[lch[a]]+sum[lch[b]]-sum[lch[c]]-sum[lch[d]]);
     89         if(k<=tmp)
     90             r=mid,a=lch[a],b=lch[b],c=lch[c],d=lch[d];
     91         else
     92             k-=tmp,l=mid+1,a=rch[a],b=rch[b],c=rch[c],d=rch[d];
     93     }
     94     return num[l];
     95 }
     96 int ans;
     97 int main(){
     98     memset(pre,NULL,sizeof(pre));
     99     n=read(),m=read();
    100     for(int i=1;i<=n;++i)
    101         num[i]=v[i]=read();
    102     for(int i=1;i<n;++i){
    103         int x(read()),y(read());
    104         insert(x,y),insert(y,x);
    105     }
    106     sort(num+1,num+n+1);
    107     size=unique(num+1,num+n+1)-num-1;
    108     for(int i=1;i<=n;++i)
    109         v[i]=lower_bound(num+1,num+size+1,v[i])-num;
    110     dfs(1);
    111     build(rt[0],1,size);
    112     for(int i=1;i<=n;++i)
    113         update(rt[i],rt[l[fa[pos[i]][0]]],v[pos[i]],1,size);
    114     while(m--){
    115         int x(read()),y(read()),k(read());
    116         x^=ans;
    117         ans=query(x,y,k);
    118         if(!m)
    119             printf("%d",ans);
    120         else
    121             printf("%d
    ",ans);
    122     }
    123 }
    Count

    [Poi2014]Couriers

    太水,没写博客,基本上就是板子

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 inline int read(){
     6     int sum(0);
     7     char ch(getchar());
     8     for(;ch<'0'||ch>'9';ch=getchar());
     9     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
    10     return sum;
    11 }
    12 int n,m;
    13 int cnt;
    14 int a[500005];
    15 int rt[15000005],sum[15000005],lch[15000005],rch[15000005];
    16 inline void build(int &x,int l,int r){
    17     x=++cnt;
    18     sum[x]=0;
    19     if(l==r)
    20         return;
    21     int mid((l+r)>>1);
    22     build(lch[x],l,mid);
    23     build(rch[x],mid+1,r);
    24 }
    25 inline void update(int &x,int las,int pos,int l,int r){
    26     x=++cnt;
    27     lch[x]=lch[las];
    28     rch[x]=rch[las];
    29     sum[x]=sum[las]+1;
    30     if(l==r)
    31         return;
    32     int mid((l+r)>>1);
    33     if(pos<=mid)
    34         update(lch[x],lch[las],pos,l,mid);
    35     else
    36         update(rch[x],rch[las],pos,mid+1,r);
    37 }
    38 inline int query(int x,int y,int l,int r,int k){
    39     if(l==r){
    40         if(sum[y]-sum[x]<=k)
    41             return 0;
    42         return l;
    43     }
    44     int mid((l+r)>>1);
    45     if(sum[lch[y]]-sum[lch[x]]>k)
    46         return query(lch[x],lch[y],l,mid,k);
    47     if(sum[rch[y]]-sum[rch[x]]>k)
    48         return query(rch[x],rch[y],mid+1,r,k);
    49     return 0;
    50 }
    51 int main(){
    52     n=read(),m=read();
    53     for(int i=1;i<=n;++i)
    54         a[i]=read();
    55     build(rt[0],1,n);
    56     for(int i=1;i<=n;++i)
    57         update(rt[i],rt[i-1],a[i],1,n);
    58     while(m--){
    59         int l(read()),r(read());
    60         printf("%d
    ",query(rt[l-1],rt[r],1,n,(r-l+1)>>1));
    61     }
    62 }
    Couriers

    [BZOJ3653]谈笑风生

    这道题没来得及写博客,以深度建树,维护$size$的和,$x$,$y$的答案=$size[x] imes min(deep[x],y)+dfs$序在$l[x]$到$r[x]$之间且深度在$deep[x]+1$到$deep[x]+k$之间的$size$和(话说这道题扔这个板块合适吗= =)

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 inline int read(){
     7     int sum(0);
     8     char ch(getchar());
     9     for(;ch<'0'||ch>'9';ch=getchar());
    10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
    11     return sum;
    12 }
    13 struct edge{
    14     int e;
    15     edge *n;
    16 }a[600005],*pre[300005];
    17 int tot;
    18 inline void insert(int s,int e){
    19     a[++tot].e=e;
    20     a[tot].n=pre[s];
    21     pre[s]=&a[tot];
    22 }
    23 typedef long long L;
    24 int n,q;
    25 int timee;
    26 int l[300005],r[300005],pos[300005],size[300005],fa[300005],dep[300005];
    27 inline void dfs(int u){
    28     l[u]=++timee;
    29     pos[timee]=u;
    30     size[u]=1;
    31     for(edge *i=pre[u];i;i=i->n){
    32         int e(i->e);
    33         if(e!=fa[u]){
    34             fa[e]=u;
    35             dep[e]=dep[u]+1;
    36             dfs(e);
    37             size[u]+=size[e];
    38         }
    39     }
    40     r[u]=timee;
    41 }
    42 int mx,cnt;
    43 int rt[300005],lch[6000005],rch[6000005];
    44 L sum[6000005];
    45 inline void update(int &x,int las,int pos,int w,int l,int r){
    46     x=++cnt;
    47     lch[x]=lch[las];
    48     rch[x]=rch[las];
    49     sum[x]=sum[las]+w;
    50     if(l==r)
    51         return;
    52     int mid((l+r)>>1);
    53     if(pos<=mid)
    54         update(lch[x],lch[las],pos,w,l,mid);
    55     else
    56         update(rch[x],rch[las],pos,w,mid+1,r);
    57 }
    58 inline L query(int x,int y,int ll,int rr,int l,int r){
    59     if(ll<=l&&r<=rr)
    60         return sum[y]-sum[x];
    61     int mid((l+r)>>1);
    62     L ret(0);
    63     if(ll<=mid)
    64         ret+=query(lch[x],lch[y],ll,rr,l,mid);
    65     if(mid<rr)
    66         ret+=query(rch[x],rch[y],ll,rr,mid+1,r);
    67     return ret;
    68 }
    69 inline int gg(){
    70     freopen("laugh.in","r",stdin);
    71     freopen("laugh.out","w",stdout);
    72     n=read(),q=read();
    73     for(int i=1;i<n;++i){
    74         int x(read()),y(read());
    75         insert(x,y),insert(y,x);
    76     }
    77     dfs(1);
    78     for(int i=1;i<=n;++i)
    79         mx=max(dep[i],mx);
    80     for(int i=1;i<=n;++i)
    81         update(rt[i],rt[i-1],dep[pos[i]],size[pos[i]]-1,0,mx);
    82     while(q--){
    83         int x(read()),y(read());
    84         L ans(0);
    85         ans+=(L)(size[x]-1)*(L)min(dep[x],y);
    86         ans+=query(rt[l[x]],rt[r[x]],dep[x]+1,dep[x]+y,0,mx);
    87         printf("%lld
    ",ans);
    88     }
    89 }
    90 int K(gg());
    91 int main(){;}
    赛艇的谈笑风生

     动态主席树(树状数组套主席树)

    实际上没有啥,就是把维护前缀和的工具改为的树状数组式的而已,具体的只要理解的主席树与树状数组,其余的就很好打了

    [BZOJ 1901]Dynamic Rankings

    板子题

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 using namespace std;
      6 inline int read(){
      7     int sum(0);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar());
     10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     11     return sum;
     12 }
     13 int n,m;
     14 int tot,size,cnt;
     15 int v[10005],num[20005],has[20005];
     16 int rt[10005],sum[2500005],lch[2500005],rch[2500005];
     17 int A[10005],B[10005],K[10005];
     18 bool flag[10005];
     19 int a,b,L[30],R[30];
     20 char op[2];
     21 inline int lowbit(int x){
     22     return x&-x;
     23 }
     24 inline int find(int x){
     25     int l(1),r(size),mid;
     26     while(l<=r){
     27         mid=(l+r)>>1;
     28         if(has[mid]<x)
     29             l=mid+1;
     30         else
     31             r=mid-1;
     32     }
     33     return l;
     34     //return lower_bound(has+1,has+size+1,x)-has;
     35 }
     36 inline void update(int &x,int las,int pos,int w,int l,int r){
     37     x=++cnt;
     38     lch[x]=lch[las];
     39     rch[x]=rch[las];
     40     sum[x]=sum[las]+w;
     41     if(l==r)
     42         return;
     43     int mid((l+r)>>1);
     44     if(pos<=mid)
     45         update(lch[x],lch[las],pos,w,l,mid);
     46     else
     47         update(rch[x],rch[las],pos,w,mid+1,r);
     48 }
     49 inline int query(int l,int r,int k){
     50     if(l==r)
     51         return l;
     52     int suml(0),sumr(0),mid((l+r)>>1);
     53     for(int i=1;i<=a;++i)suml+=sum[lch[L[i]]];
     54     for(int i=1;i<=b;++i)sumr+=sum[lch[R[i]]];
     55     if(sumr-suml>=k){
     56         for(int i=1;i<=a;++i)L[i]=lch[L[i]];
     57         for(int i=1;i<=b;++i)R[i]=lch[R[i]];
     58         return query(l,mid,k);
     59     }
     60     else{
     61         for(int i=1;i<=a;++i)L[i]=rch[L[i]];
     62         for(int i=1;i<=b;++i)R[i]=rch[R[i]];
     63         return query(mid+1,r,k-(sumr-suml));
     64     }
     65 }
     66 int main(){
     67     n=read(),m=read();
     68     for(int i=1;i<=n;++i){
     69         v[i]=read();
     70         num[++tot]=v[i];
     71     }
     72     for(int i=1;i<=m;++i){
     73         scanf("%s",op);
     74         if(op[0]=='Q'){
     75             flag[i]=1;
     76             A[i]=read();
     77             B[i]=read();
     78             K[i]=read();
     79         }
     80         else{
     81             A[i]=read();
     82             B[i]=read();
     83             num[++tot]=B[i];
     84         }
     85     }
     86     sort(num+1,num+tot+1);
     87     has[++size]=num[1];
     88     for(int i=2;i<=tot;++i)
     89         if(num[i]!=num[i-1])
     90             has[++size]=num[i];
     91     for(int i=1;i<=n;++i){
     92         int tmp(find(v[i]));
     93         for(int j=i;j<=n;j+=lowbit(j))
     94             update(rt[j],rt[j],tmp,1,1,size);
     95     }
     96     for(int i=1;i<=m;++i){
     97         if(flag[i]){
     98             a=b=0;
     99             --A[i];
    100             for(int j=A[i];j>0;j-=lowbit(j))
    101                 L[++a]=rt[j];
    102             for(int j=B[i];j>0;j-=lowbit(j))
    103                 R[++b]=rt[j];
    104             printf("%d
    ",has[query(1,size,K[i])]);
    105         }
    106         else{
    107             int tmp(find(v[A[i]]));
    108             for(int j=A[i];j<=n;j+=lowbit(j))
    109                 update(rt[j],rt[j],tmp,-1,1,size);
    110             v[A[i]]=B[i];
    111             tmp=find(B[i]);
    112             for(int j=A[i];j<=n;j+=lowbit(j))
    113                 update(rt[j],rt[j],tmp,1,1,size);
    114         }
    115     }
    116 }
    Dynamic

    [CQOI2015]任务查询系统

    其实是静态的,但是要用树状数组套一下,所以就扔在这里了

    差分一下,瞎XX乱搞就行了

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 using namespace std;
      6 typedef long long L;
      7 inline L read(){
      8     L sum(0),f(1);
      9     char ch(getchar());
     10     for(;ch<'0'||ch>'9';ch=getchar())
     11         if(ch=='-')
     12             f=-1;
     13     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     14     return sum*f;
     15 }
     16 int m,n;
     17 int cnt,tot;
     18 int q[100005],top;
     19 int s[100005],e[100005],p[100005],num[100005];
     20 int rt[100005],size[20000005],lch[20000005],rch[20000005];
     21 L sum[20000005];
     22 L ans(1),x,a,b,c,k;
     23 inline int lowbit(int x){
     24     return x&-x;
     25 }
     26 inline int insert(int x,int val,int f){
     27     if(!x)
     28         x=++cnt;
     29     size[x]+=f;
     30     sum[x]+=f*num[val];
     31     int tmp(x);
     32     int l(1),r(m);
     33     while(l<r){
     34         int mid((l+r)>>1);
     35         if(val<=mid){
     36             r=mid;
     37             if(!lch[x])
     38                 lch[x]=++cnt;
     39             x=lch[x];
     40             size[x]+=f;
     41             sum[x]+=f*num[val];
     42         }
     43         else{
     44             l=mid+1;
     45             if(!rch[x])
     46                 rch[x]=++cnt;
     47             x=rch[x];
     48             size[x]+=f;
     49             sum[x]+=f*num[val];
     50         }
     51     }
     52     return tmp;
     53 }
     54 inline void update(int x,int val,int f){
     55     for(int i=x;i<=n;i+=lowbit(i))
     56         rt[i]=insert(rt[i],val,f);
     57 }
     58 inline L query(int x,int k){
     59     L ret(0),tot(0);
     60     top=0;
     61     for(int i=x;i>0;i-=lowbit(i)){
     62         q[++top]=rt[i];
     63         tot+=size[rt[i]];
     64         ret+=sum[rt[i]];
     65     }
     66     if(k>tot)
     67         return ret;
     68     ret=0;
     69     int l(1),r(m);
     70     while(l<r){
     71         int mid((l+r)>>1),tmp(0);
     72         for(int i=1;i<=top;++i)
     73             tmp+=size[lch[q[i]]];
     74         if(tmp<k){
     75             for(int i=1;i<=top;++i)
     76                 ret+=sum[lch[q[i]]];
     77             k-=tmp;
     78             l=mid+1;
     79             for(int i=1;i<=top;++i)
     80                 q[i]=rch[q[i]];
     81         }
     82         else{
     83             r=mid;
     84             for(int i=1;i<=top;++i)
     85                 q[i]=lch[q[i]];
     86         }
     87     }
     88     ret+=1LL*k*num[l];
     89     return ret;
     90 }
     91 int main(){
     92     m=read(),n=read();
     93     for(int i=1;i<=m;++i)
     94         s[i]=read(),e[i]=read(),num[i]=p[i]=read();
     95     sort(num+1,num+m+1);
     96     tot=unique(num+1,num+m+1)-num-1;
     97     for(int i=1;i<=m;++i){
     98         p[i]=lower_bound(num+1,num+tot+1,p[i])-num;
     99         update(s[i],p[i],1);
    100         update(e[i]+1,p[i],-1);
    101     }
    102     for(int i=1;i<=n;++i){
    103         x=read(),a=read(),b=read(),c=read();
    104         k=1+(a*ans+b)%c;
    105         ans=query(x,k);
    106         printf("%lld
    ",ans);
    107     }
    108 }
    CQOI2015

    [BZOJ 4999]This Problem Is Too Simple!

    树剖上乱搞

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<map>
      5 using namespace std;
      6 inline int read(){
      7     int sum(0);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar());
     10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     11     return sum;
     12 }
     13 struct edge{
     14     int e;
     15     edge *n;
     16 }ed[200005],*pre[100005];
     17 int tot;
     18 inline void insert(int s,int e){
     19     ed[++tot].e=e;
     20     ed[tot].n=pre[s];
     21     pre[s]=&ed[tot];
     22 }
     23 map<int,int>ma;
     24 int num;
     25 int n,q;
     26 int a[100005];
     27 int dep[100005],size[100005],fa[100005],son[100005];
     28 inline void dfs1(int u){
     29     size[u]=1;
     30     son[u]=0;
     31     for(edge *i=pre[u];i;i=i->n){
     32         int e(i->e);
     33         if(e!=fa[u]){
     34             fa[e]=u;
     35             dep[e]=dep[u]+1;
     36             dfs1(e);
     37             size[u]+=size[e];
     38             if(size[e]>size[son[u]])
     39                 son[u]=e;
     40         }
     41     }
     42 }
     43 int timee;
     44 int id[100005],pos[100005],top[100005];
     45 inline void dfs2(int u,int rt){
     46     top[u]=rt;
     47     id[u]=++timee;
     48     pos[timee]=u;
     49     if(son[u])
     50         dfs2(son[u],rt);
     51     for(edge *i=pre[u];i;i=i->n){
     52         int e(i->e);
     53         if(e!=fa[u]&&e!=son[u])
     54             dfs2(e,e);
     55     }
     56 }
     57 int cnt;
     58 int rt[300005],lch[12000005],rch[12000005],sum[12000005];
     59 inline void update(int &x,int pos,int w,int l,int r){
     60     if(!x)
     61         x=++cnt;
     62     sum[x]+=w;
     63     if(l==r)
     64         return;
     65     int mid((l+r)>>1);
     66     if(pos<=mid)
     67         update(lch[x],pos,w,l,mid);
     68     else
     69         update(rch[x],pos,w,mid+1,r);
     70 }
     71 inline int query(int x,int ll,int rr,int l,int r){
     72     if(!x)
     73         return 0;
     74     if(ll<=l&&r<=rr)
     75         return sum[x];
     76     int mid((l+r)>>1),ret(0);
     77     if(ll<=mid)
     78         ret+=query(lch[x],ll,rr,l,mid);
     79     if(mid<rr)
     80         ret+=query(rch[x],ll,rr,mid+1,r);
     81     return ret;
     82 }
     83 inline int ask(int x,int y,int z){
     84     int ret(0),tmp(ma[z]);
     85     while(top[x]^top[y]){
     86         if(dep[top[x]]<dep[top[y]])
     87             swap(x,y);
     88         ret+=query(rt[tmp],id[top[x]],id[x],1,n);
     89         x=fa[top[x]];
     90     }
     91     if(dep[x]>dep[y])
     92         swap(x,y);
     93     ret+=query(rt[tmp],id[x],id[y],1,n);
     94     return ret;
     95 }
     96 char op[2];
     97 int main(){
     98     memset(pre,NULL,sizeof(pre));
     99     n=read(),q=read();
    100     for(int i=1;i<=n;++i)
    101         a[i]=read();
    102     for(int i=1;i<n;++i){
    103         int x(read()),y(read());
    104         insert(x,y),insert(y,x);
    105     }
    106     dfs1(1);
    107     dfs2(1,1);
    108     for(int i=1;i<=n;++i){
    109         if(!ma[a[i]])
    110             ma[a[i]]=++num;
    111         update(rt[ma[a[i]]],id[i],1,1,n);
    112     }
    113     while(q--){
    114         scanf("%s",op);
    115         if(op[0]=='C'){
    116             int x(read()),y(read());
    117             update(rt[ma[a[x]]],id[x],-1,1,n);
    118             if(!ma[y])
    119                 ma[y]=++num;
    120             a[x]=y;
    121             update(rt[ma[y]],id[x],1,1,n);
    122         }
    123         else{
    124             int x(read()),y(read()),z(read());
    125             if(!ma[z])
    126                 puts("0");
    127             else
    128                 printf("%d
    ",ask(x,y,z));
    129         }
    130     }
    131 }
    图样图森破

    突然发现根本没做几道题,我好弱啊QAQ

    可。。。可。。。可持久化?

    真正的可持久化到来,有关历史版本的修改与查询,实际上理解了主席树的修改操作,这个就变得异常的简单起来

    [COGS 2554][福利]可持久化线段树

    单点修改的板子题,没啥好说的

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 inline int read(){
     6     int sum(0);
     7     char ch(getchar());
     8     for(;ch<'0'||ch>'9';ch=getchar());
     9     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
    10     return sum;
    11 }
    12 int n,q,t(1);
    13 int a[10005];
    14 int cnt;
    15 int rt[100005],lch[20000005],rch[20000005],mx[20000005];
    16 inline void pushup(int i){
    17     mx[i]=max(mx[lch[i]],mx[rch[i]]);
    18 }
    19 inline void build(int &x,int l,int r){
    20     x=++cnt;
    21     if(l==r){
    22         mx[x]=a[l];
    23         return;
    24     }
    25     int mid((l+r)>>1);
    26     build(lch[x],l,mid);
    27     build(rch[x],mid+1,r);
    28     pushup(x);
    29 }
    30 inline void update(int &x,int las,int pos,int w,int l,int r){
    31     x=++cnt;
    32     lch[x]=lch[las];
    33     rch[x]=rch[las];
    34     mx[x]=mx[las];
    35     if(l==r){
    36         mx[x]=w;
    37         return;
    38     }
    39     int mid((l+r)>>1);
    40     if(pos<=mid)
    41         update(lch[x],lch[las],pos,w,l,mid);
    42     else
    43         update(rch[x],rch[las],pos,w,mid+1,r);
    44     pushup(x);
    45 }
    46 inline int query(int x,int ll,int rr,int l,int r){
    47     if(ll==l&&r==rr)
    48         return mx[x];
    49     int mid((l+r)>>1);
    50     if(rr<=mid)
    51         return query(lch[x],ll,rr,l,mid);
    52     if(mid<ll)
    53         return query(rch[x],ll,rr,mid+1,r);
    54     return max(query(lch[x],ll,mid,l,mid),query(rch[x],mid+1,rr,mid+1,r));
    55 }
    56 inline int gg(){
    57     freopen("longterm_segtree.in","r",stdin);
    58     freopen("longterm_segtree.out","w",stdout);
    59     n=read(),q=read();
    60     for(int i=1;i<=n;++i)
    61         a[i]=read();
    62     build(rt[1],1,n);
    63     while(q--){
    64         int op(read()),x(read()),y(read()),z(read());
    65         if(op==0)
    66             printf("%d
    ",query(rt[x],y,z,1,n));
    67         else
    68             update(rt[++t],rt[x],y,z,1,n);
    69     }
    70     return 0;
    71 }
    72 int K(gg());
    73 int main(){;}
    longterm_segtree

    [HDU 4348]To the moon

    可持久化线段树区间修改的板子题

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 using namespace std;
      5 typedef long long L;
      6 inline int read(){
      7     int sum(0),f(1);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar())
     10         if(ch=='-')
     11             f=-1;
     12     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     13     return sum*f;
     14 }
     15 int n,m,t,cnt;
     16 int v[100005];
     17 int rt[100005],lch[4000005],rch[4000005];
     18 L sum[4000005],add[4000005];
     19 char op[2];
     20 inline int build(int l,int r){
     21     int x(++cnt);
     22     add[x]=0;
     23     if(l==r){
     24         sum[x]=v[l];
     25         lch[x]=rch[x]=0;
     26 //        cout<<"pos "<<x<<" "<<l<<' '<<r<<" "<<v[l]<<' '<<sum[x]<<endl;
     27         return x;
     28     }
     29     int mid((l+r)>>1);
     30     lch[x]=build(l,mid);
     31 //    cout<<"left child"<<x<<" "<<lch[x]<<' '<<sum[lch[x]]<<endl;
     32     rch[x]=build(mid+1,r);
     33 //    cout<<"right child"<<x<<" "<<rch[x]<<' '<<sum[rch[x]]<<endl;
     34 //    cout<<"wtf"<<endl;
     35     sum[x]=sum[lch[x]]+sum[rch[x]];
     36 //    cout<<"wtf"<<endl;
     37 //    cout<<x<<" "<<l<<' '<<r<<" "<<lch[x]<<' '<<rch[x]<<' '<<sum[lch[x]]<<' '<<sum[rch[x]]<<' '<<sum[x]<<endl;
     38     return x;
     39 }
     40 inline void pushup(int x,int len){
     41     sum[x]=sum[lch[x]]+sum[rch[x]]+add[lch[x]]*(len-(len>>1))+add[rch[x]]*(len>>1);
     42 }
     43 inline int update(int rt,int ll,int rr,L w,int l,int r){
     44     int newrt(++cnt);
     45     add[newrt]=add[rt];
     46     if(ll<=l&&r<=rr){
     47         sum[newrt]=sum[rt];
     48         add[newrt]=add[rt]+w;
     49         lch[newrt]=lch[rt];
     50         rch[newrt]=rch[rt];
     51         return newrt;
     52     }
     53     int mid((l+r)>>1);
     54     if(ll<=mid)
     55         lch[newrt]=update(lch[rt],ll,rr,w,l,mid);
     56     else
     57         lch[newrt]=lch[rt];
     58     if(mid<rr)
     59         rch[newrt]=update(rch[rt],ll,rr,w,mid+1,r);
     60     else
     61         rch[newrt]=rch[rt];
     62     pushup(newrt,r-l+1);
     63     return newrt;
     64 }
     65 inline L query(int rt,int ll,int rr,int l,int r,L add1){
     66 //    cout<<rt<<' '<<ll<<' '<<rr<<' '<<l<<' '<<r<<' '<<add1<<endl;
     67     if(ll<=l&&r<=rr)
     68         return sum[rt]+(add1+add[rt])*(r-l+1);
     69     int mid((l+r)>>1);
     70     L ret(0);
     71     if(ll<=mid)
     72         ret+=query(lch[rt],ll,rr,l,mid,add[rt]+add1);
     73     if(mid<rr)
     74         ret+=query(rch[rt],ll,rr,mid+1,r,add[rt]+add1);
     75     return ret;
     76 }
     77 int main(){
     78     int flag(0);
     79     while(scanf("%d%d",&n,&m)==2){
     80         if(flag)
     81             puts("");
     82         for(int i=1;i<=n;++i)
     83             v[i]=read();
     84         ++flag;
     85         cnt=t=0;
     86         rt[0]=build(1,n);
     87         while(m--){
     88             scanf("%s",op);
     89             if(op[0]=='Q'){
     90                 int x(read()),y(read());
     91                 printf("%lld
    ",query(rt[t],x,y,1,n,0));
     92             }
     93             if(op[0]=='C'){
     94                 int x(read()),y(read());
     95                 L z(read());
     96                 rt[t+1]=update(rt[t],x,y,z,1,n);
     97                 ++t;
     98             }
     99             if(op[0]=='H'){
    100                 int x(read()),y(read()),z(read());
    101                 printf("%lld
    ",query(rt[z],x,y,1,n,0));
    102             }
    103             if(op[0]=='B'){
    104                 int x(read());
    105                 t=x;
    106                 cnt=rt[t+1]-1;
    107             }
    108         }
    109     }
    110 }
    moon

    [BZOJ 3221]Obserbing the tree树上询问

    真正做过的难题出现!

    树剖+可持久化线段树区间修改+线段树上维护等差数列(其实没多难,我太弱而已= =)

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 using namespace std;
      5 typedef long long L;
      6 inline L read(){
      7     L sum(0),f(1);
      8     char ch(getchar());
      9     for(;ch<'0'||ch>'9';ch=getchar())
     10         if(ch=='-')
     11             f=-1;
     12     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     13     return sum*f;
     14 }
     15 struct edge{
     16     int e;
     17     edge *n;
     18 }a[200005],*pre[100005];
     19 int to;
     20 inline void insert(int s,int e){
     21     a[++to].e=e;
     22     a[to].n=pre[s];
     23     pre[s]=&a[to];
     24 }
     25 int n,m,now,tot;
     26 char op[2];
     27 int dep[100005],size[100005],fa[100005],son[100005];
     28 inline void dfs1(int u){
     29     size[u]=1;
     30     son[u]=0;
     31     dep[u]=dep[fa[u]]+1;
     32     for(edge *i=pre[u];i;i=i->n){
     33         int e(i->e);
     34         if(e!=fa[u]){
     35             fa[e]=u;
     36             dfs1(e);
     37             size[u]+=size[e];
     38             if(size[e]>size[son[u]])
     39                 son[u]=e;
     40         }
     41     }
     42 }
     43 int timee;
     44 int id[100005],top[100005];
     45 inline void dfs2(int u,int rt){
     46     top[u]=rt;
     47     id[u]=++timee;
     48     if(son[u])
     49         dfs2(son[u],rt);
     50     for(edge *i=pre[u];i;i=i->n){
     51         int e(i->e);
     52         if(e!=son[u]&&e!=fa[u])
     53             dfs2(e,e);
     54     }
     55 }
     56 inline int lca(int x,int y){
     57     while(top[x]^top[y]){
     58         if(dep[top[x]]<dep[top[y]])
     59             swap(x,y);
     60         x=fa[top[x]];
     61     }
     62     return dep[x]<dep[y]?x:y;
     63 }
     64 int rt[100005],lch[20000005],rch[20000005];
     65 int cnt;
     66 L sum[20000005],add_sx[20000005],add_gc[20000005];
     67 L ans;
     68 inline void update(int &x,int las,int ll,int rr,L sx,L gc,int l,int r){
     69     x=++cnt;
     70     lch[x]=lch[las];
     71     rch[x]=rch[las];
     72     sum[x]=sum[las];
     73     add_sx[x]=add_sx[las];
     74     add_gc[x]=add_gc[las];
     75     if(ll==l&&r==rr){
     76         add_sx[x]+=sx;
     77         add_gc[x]+=gc;
     78         return;
     79     }
     80     sum[x]+=(sx+sx+gc*(L)(rr-ll))*(rr-ll+1)/2;
     81     int mid((l+r)>>1);
     82     if(rr<=mid)
     83         update(lch[x],lch[las],ll,rr,sx,gc,l,mid);
     84     else
     85         if(mid<ll)
     86             update(rch[x],rch[las],ll,rr,sx,gc,mid+1,r);
     87         else{
     88             update(lch[x],lch[las],ll,mid,sx,gc,l,mid);
     89             update(rch[x],rch[las],mid+1,rr,sx+(mid-ll+1)*gc,gc,mid+1,r);
     90         }
     91 }
     92 inline L query(int x,int ll,int rr,int l,int r){
     93     L ret((add_sx[x]+(ll-l)*add_gc[x]+add_sx[x]+(rr-l)*add_gc[x])*(rr-ll+1)/2);
     94     if(ll==l&&r==rr)
     95         return ret+sum[x];
     96     int mid((l+r)>>1);
     97     if(rr<=mid)
     98         return ret+query(lch[x],ll,rr,l,mid);
     99     if(mid<ll)
    100         return ret+=query(rch[x],ll,rr,mid+1,r);
    101     return ret+query(lch[x],ll,mid,l,mid)+query(rch[x],mid+1,rr,mid+1,r);
    102 }
    103 inline void change(int x,int y,L sx,L gc){
    104     int f(lca(x,y));
    105     L tp1(0),tp2(dep[x]+dep[y]-dep[f]*2+2);
    106     while(top[x]^top[f]){
    107         tp1+=dep[x]-dep[top[x]]+1;
    108         update(rt[now],rt[now],id[top[x]],id[x],sx+(tp1-1)*gc,-gc,1,n);
    109         x=fa[top[x]];
    110     }
    111     while(top[y]^top[f]){
    112         tp2-=dep[y]-dep[top[y]]+1;
    113         update(rt[now],rt[now],id[top[y]],id[y],sx+(tp2-1)*gc,gc,1,n);
    114         y=fa[top[y]];
    115     }
    116     ++tp1;
    117     --tp2;
    118     if(dep[x]<dep[y])
    119         update(rt[now],rt[now],id[x],id[y],sx+(tp1-1)*gc,gc,1,n);
    120     else
    121         update(rt[now],rt[now],id[y],id[x],sx+(tp2-1)*gc,-gc,1,n);
    122 }
    123 inline L ask(int x,int y){
    124     L ret(0);
    125     while(top[x]^top[y]){
    126         if(dep[top[x]]<dep[top[y]])
    127             swap(x,y);
    128         ret+=query(rt[now],id[top[x]],id[x],1,n);
    129         x=fa[top[x]];
    130     }
    131     if(dep[x]>dep[y])
    132         swap(x,y);
    133     ret+=query(rt[now],id[x],id[y],1,n);
    134     return ret;
    135 }
    136 int main(){
    137     memset(pre,NULL,sizeof(pre));
    138     n=read(),m=read();
    139     for(int i=1;i<n;++i){
    140         int x(read()),y(read());
    141         insert(x,y),insert(y,x);
    142     }
    143     dfs1(1);
    144     dfs2(1,1);
    145     while(m--){
    146         scanf("%s",op);
    147         if(op[0]=='c'){
    148             L x(read()),y(read()),sx(read()),gc(read());
    149             x^=ans,y^=ans;
    150             rt[++tot]=rt[now];
    151             now=tot;
    152             change(x,y,sx,gc);
    153         }
    154         if(op[0]=='q'){
    155             L x(read()),y(read());
    156             x^=ans,y^=ans;
    157             ans=ask(x,y);
    158             printf("%lld
    ",ans);
    159         }
    160         if(op[0]=='l'){
    161             L x(read());
    162             x^=ans;
    163             now=x;
    164         }
    165     }
    166 }
    Obserbing

    REAL 小结?

    反正主席树这东西用处不少,就是联赛貌似用不到,所以只能期望自己能撑过联赛,自己也要加油啊

  • 相关阅读:
    MySQL技术内幕 InnoDB存储引擎 之 InnoDB体系架构
    ORACLE同义词使用
    五大好用的开源MySQL管理工具推荐
    MySQL Online DDL工具
    10046事件及其用法介绍
    MySQL表碎片清理
    MyRocks安装部署
    TiDB单机安装测试
    TiDB官方文档
    GoldenGate—AUTORESTART配置
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7616133.html
Copyright © 2011-2022 走看看