树链剖分

不是树剖教程,是一些写码时候发现的问题

具体树剖教程可以参考博文https://www.cnblogs.com/chinhhh/p/7965433.html

 

 

  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 using namespace std;
  4 const int N=1e5+11,M=2e5+11,tree_Sz=5e5+11,MAXX=1<<29;
  5 int n,m,root;
  6 ll p,a[N];
  7 int to[M],nxt[M],edge,head[N];
  8 int fa[N],dep[N],sz[N],son[N];
  9 int top[N],cnt,seg[N],rev[N];
 10 
 11 inline int read_int() {
 12     char ch=getchar(); int x=0,f=1;
 13     while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
 14     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 15     return x*f;
 16 }
 17 
 18 inline ll read_ll() {
 19     char ch=getchar(); ll x=0,f=1;
 20     while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
 21     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
 22     return x*f;
 23 }
 24 
 25 struct SegmentTree {
 26     struct Node {
 27         ll val,tag;
 28     };
 29     Node t[tree_Sz];
 30     inline void pushup(int d) {
 31         t[d].val=(t[d<<1].val+t[d<<1|1].val)%p;
 32     }
 33     inline void pushdown(int d,int l,int r) {
 34         ll &tg=t[d].tag;
 35         if(!tg) return ;
 36         (t[d<<1].tag+=tg)%=p;
 37         (t[d<<1|1].tag+=tg)%=p;
 38         int mid=(l+r)>>1;
 39         (t[d<<1].val+=tg*(mid-l+1))%=p;
 40         (t[d<<1|1].val+=tg*(r-mid))%=p;
 41         tg=0;
 42     }
 43     void build(int d,int l,int r) {
 44         if(l==r) {
 45             t[d].val=a[rev[l]];
 46             return ;
 47         }
 48         int mid=(l+r)>>1;
 49         build(d<<1,l,mid);
 50         build(d<<1|1,mid+1,r);
 51         pushup(d);
 52     }
 53     inline void Build() {
 54         build(1,1,n);
 55     }
 56     void modify(int d,int l,int r,int x,int y,int z) {
 57         if(x<=l && r<=y) {
 58             (t[d].tag+=z)%=p;
 59             (t[d].val+=z*(r-l+1))%=p;
 60             return ;
 61         }
 62         pushdown(d,l,r);
 63         int mid=(l+r)>>1;
 64         if(x<=mid) modify(d<<1,l,mid,x,y,z);
 65         if(y>=mid+1) modify(d<<1|1,mid+1,r,x,y,z);
 66         pushup(d);
 67     }
 68     inline void Modify(int x,int y,ll z) {
 69         modify(1,1,n,x,y,z);
 70     }
 71     ll query(int d,int l,int r,int x,int y) {
 72         if(x<=l && r<=y) {
 73             return t[d].val;
 74         }
 75         pushdown(d,l,r);
 76         int mid=(l+r)>>1;
 77         ll res=0;
 78         if(x<=mid) (res+=query(d<<1,l,mid,x,y))%=p;
 79         if(y>=mid+1) (res+=query(d<<1|1,mid+1,r,x,y))%=p;
 80         return res;
 81     }
 82     inline ll Query(int x,int y) {
 83         return query(1,1,n,x,y);
 84     }
 85 }st;
 86 
 87 inline void addedge(int x,int y) {
 88     ++edge,to[edge]=y,nxt[edge]=head[x],head[x]=edge;
 89     ++edge,to[edge]=x,nxt[edge]=head[y],head[y]=edge;
 90 }
 91 
 92 void dfs1(int d,int f) {
 93     fa[d]=f,dep[d]=dep[f]+1,++sz[d];
 94     int maxx=0;
 95     for(int i=head[d];i;i=nxt[i]) {
 96         int u=to[i];
 97         if(u==f) continue;
 98         dfs1(u,d);
 99         sz[d]+=sz[u];
100         if(sz[u]>maxx) maxx=sz[u],son[d]=u;
101     }
102 }
103 
104 void dfs2(int d) {
105     if(son[d]) {
106         int u=son[d];
107         seg[u]=++cnt,rev[cnt]=u,top[u]=top[d];
108         dfs2(u);
109     }
110     for(int i=head[d];i;i=nxt[i]) {
111         int u=to[i];
112         if(u==fa[d] || u==son[d]) continue;
113         seg[u]=++cnt,rev[cnt]=u,top[u]=u;
114         dfs2(u);
115     }
116 }
117 
118 inline void Update1(int x,int y,ll z) {
119     int fx=top[x],fy=top[y];
120     while(fx!=fy) {
121         if(dep[fx]<dep[fy]) x^=y^=x^=y,fx^=fy^=fx^=fy;
122         st.Modify(seg[fx],seg[x],z);
123         x=fa[fx],fx=top[x];
124     }
125     if(dep[x]>dep[y]) x^=y^=x^=y;
126     st.Modify(seg[x],seg[y],z);
127 }
128 
129 inline void Update2(int x,ll z) {
130     st.Modify(seg[x],seg[x]+sz[x]-1,z);
131 }
132 
133 inline void Ask1(int x,int y) {
134     int fx=top[x],fy=top[y];
135     ll res=0;
136     while(fx!=fy) {
137         if(dep[fx]<dep[fy]) x^=y^=x^=y,fx^=fy^=fx^=fy;
138         (res+=st.Query(seg[fx],seg[x]))%=p;
139         x=fa[fx],fx=top[x];
140     }
141     if(dep[x]>dep[y]) x^=y^=x^=y;
142     (res+=st.Query(seg[x],seg[y]))%=p;
143     printf("%lld\n",res);
144 }
145 
146 inline void Ask2(int x) {
147     printf("%lld\n",st.Query(seg[x],seg[x]+sz[x]-1));
148 }
149 
150 inline void print_test() {
151     for(int i=0;i<=n;++i) cout<<setw(3)<<i; puts("");
152     for(int i=0;i<=n;++i) cout<<setw(3)<<a[i]; puts("");
153     for(int i=0;i<=n;++i) cout<<setw(3)<<fa[i]; puts("");
154     for(int i=0;i<=n;++i) cout<<setw(3)<<dep[i]; puts("");
155     for(int i=0;i<=n;++i) cout<<setw(3)<<sz[i]; puts("");
156     for(int i=0;i<=n;++i) cout<<setw(3)<<son[i]; puts("");
157     for(int i=0;i<=n;++i) cout<<setw(3)<<top[i]; puts("");
158     for(int i=0;i<=n;++i) cout<<setw(3)<<seg[i]; puts("");
159     for(int i=0;i<=n;++i) cout<<setw(3)<<rev[i]; puts("");
160 }
161 
162 int main()
163 {
164     int op,x,y; ll z;
165     n=read_int(),m=read_int(),root=read_int(),p=read_ll();
166     for(int i=1;i<=n;++i) a[i]=read_ll();
167     for(int i=1;i<=n-1;++i) x=read_int(),y=read_int(),addedge(x,y);
168     dfs1(root,0);
169     seg[root]=++cnt,rev[cnt]=root,top[root]=root;
170     dfs2(root);
171     st.Build();
172 
173 //    print_test();
174 
175     for(int i=1;i<=m;++i) {
176         op=read_int();
177         if(op==1) x=read_int(),y=read_int(),z=read_ll(),Update1(x,y,z);
178         else if(op==2) x=read_int(),y=read_int(),Ask1(x,y);
179         else if(op==3) x=read_int(),y=read_ll(),Update2(x,y);
180         else x=read_int(),Ask2(x);
181     }
182     return 0;
183 }

 

posted @ 2021-08-12 21:39  上官书房  阅读(34)  评论(2)    收藏  举报