真正的危机不是机器人像人一样思考,而是人像机器一样思考。 ——凉宫春日的忧郁

[可持久化线段树][主席树]小结

前言

今天机房莫名掀起了一股学习主席树的浪潮,然而这对于早几天接触主席树的我,岂不是个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\n",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\n",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\n",query(rt[l-1],rt[r],1,n,(r-l+1)>>1));
61     }
62 }
Couriers

[BZOJ3653]谈笑风生

这道题没来得及写博客,以深度建树,维护$size$的和,$x$,$y$的答案=$size[x]\times 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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",ans);
159         }
160         if(op[0]=='l'){
161             L x(read());
162             x^=ans;
163             now=x;
164         }
165     }
166 }
Obserbing

REAL 小结?

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

posted @ 2017-09-30 21:25  Hzoi_Mafia  阅读(165)  评论(0编辑  收藏  举报
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。 ——死神