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

树链剖分_c++

 

 



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 }