树链剖分
study from:
http://www.cnblogs.com/chinhhh/p/7965433.html
https://www.luogu.org/problemnew/show/P3384
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9 #include <list> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <bitset> 14 #include <ext/rope> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define ll long long 19 #define minv 1e-6 20 #define inf 1e9 21 #define pi 3.1415926536 22 #define nl 2.7182818284 23 //const ll mod=1e9+7;//998244353 24 const int maxn=1e5+10; 25 26 struct node 27 { 28 int d; 29 node *next; 30 }*e[maxn]; 31 32 ll mod,tag[maxn<<2],sum[maxn<<2]; 33 int dep[maxn],siz[maxn],fa[maxn]={0},son[maxn],id[maxn],top[maxn],num=0,n; 34 bool vis[maxn]={0}; 35 ll v[maxn],point_num=0,old_id[maxn]; 36 37 void dfs1(int d,int deep) 38 { 39 node *p=e[d]; 40 int maxson=0,dd; 41 vis[d]=1; 42 dep[d]=deep; 43 siz[d]=1; 44 while (p) 45 { 46 dd=p->d; 47 if (!vis[dd]) 48 { 49 fa[dd]=d; 50 dfs1(dd,deep+1); 51 siz[d]+=siz[dd]; 52 if (siz[dd]>maxson) 53 son[d]=dd,maxson=siz[dd]; 54 } 55 p=p->next; 56 } 57 } 58 59 void dfs2(int d,int topd) 60 { 61 id[d]=++num; 62 top[d]=topd; 63 old_id[num]=d; 64 if (son[d]!=0) 65 { 66 dfs2(son[d],topd); 67 node *p=e[d]; 68 int dd; 69 while (p) 70 { 71 dd=p->d; 72 if (dd!=fa[d] && dd!=son[d]) 73 dfs2(dd,dd); 74 p=p->next; 75 } 76 } 77 } 78 79 void build(int index,int l,int r) 80 { 81 tag[index]=0; 82 if (l==r) 83 { 84 // scanf("%lld",&sum[index]); 85 sum[index]=v[old_id[++point_num]]; 86 // sum[index]=sum[index]%mod; 87 } 88 else 89 { 90 int m=(l+r)>>1; 91 build(index<<1,l,m); 92 build(index<<1|1,m+1,r); 93 sum[index]=(sum[index<<1]+sum[index<<1|1])%mod; 94 } 95 } 96 97 void push_down(int index,int len) 98 { 99 tag[index<<1]=(tag[index]+tag[index<<1])%mod; 100 tag[index<<1|1]=(tag[index]+tag[index<<1|1])%mod; 101 sum[index<<1]=(tag[index]*((len+1)>>1)+sum[index<<1])%mod; 102 sum[index<<1|1]=(tag[index]*(len>>1)+sum[index<<1|1])%mod; 103 tag[index]=0; 104 } 105 106 void update(int index,int l,int r,int x,int y,ll k) 107 { 108 if (x<=l && r<=y) 109 { 110 sum[index]=(k*(r-l+1)+sum[index])%mod; 111 tag[index]=(k+tag[index])%mod; 112 return; 113 } 114 if (tag[index]!=0) 115 push_down(index,r-l+1); 116 int m=(l+r)>>1; 117 if (x<=m) 118 update(index<<1,l,m,x,y,k); 119 if (m<y) 120 update(index<<1|1,m+1,r,x,y,k); 121 sum[index]=(sum[index<<1]+sum[index<<1|1])%mod; 122 } 123 124 ll query(int index,int l,int r,int x,int y) 125 { 126 if (x<=l && r<=y) 127 return sum[index]; 128 if (r<x || l>y) 129 return 0; 130 if (tag[index]!=0) 131 push_down(index,r-l+1); 132 int m=(l+r)>>1; 133 return (query(index<<1,l,m,x,y)+query(index<<1|1,m+1,r,x,y))%mod; 134 } 135 136 void work1(int x,int y,ll k) 137 { 138 while (top[x]!=top[y]) 139 { 140 if (dep[top[x]]<dep[top[y]]) 141 swap(x,y); 142 update(1,1,n,id[top[x]],id[x],k); 143 x=fa[top[x]]; 144 } 145 if (dep[x]<dep[y]) 146 swap(x,y); 147 update(1,1,n,id[y],id[x],k); 148 } 149 150 ll work2(int x,int y) 151 { 152 ll tot=0; 153 while (top[x]!=top[y]) 154 { 155 if (dep[top[x]]<dep[top[y]]) ///top! 156 swap(x,y); 157 tot=(tot+query(1,1,n,id[top[x]],id[x]))%mod; 158 x=fa[top[x]]; 159 } 160 if (dep[x]<dep[y]) 161 swap(x,y); 162 tot=(tot+query(1,1,n,id[y],id[x]))%mod; 163 return tot; 164 } 165 166 void work3(int x,ll k) 167 { 168 update(1,1,n,id[x],id[x]+siz[x]-1,k); 169 } 170 171 ll work4(int x) 172 { 173 return query(1,1,n,id[x],id[x]+siz[x]-1); 174 } 175 176 int main() 177 { 178 node *p; 179 int q,root,x,y,mode,i; 180 ll k; 181 scanf("%d%d%d%lld",&n,&q,&root,&mod); 182 for (i=1;i<=n;i++) 183 scanf("%lld",&v[i]); 184 for (i=1;i<n;i++) 185 { 186 scanf("%d%d",&x,&y); 187 p=(node*) malloc (sizeof(node)); 188 p->d=y; 189 p->next=e[x]; 190 e[x]=p; 191 192 p=(node*) malloc (sizeof(node)); 193 p->d=x; 194 p->next=e[y]; 195 e[y]=p; 196 } 197 198 dfs1(root,0); 199 dfs2(root,root); ///two root 200 build(1,1,n); 201 202 while (q--) 203 { 204 scanf("%d",&mode); 205 if (mode==1) 206 { 207 scanf("%d%d%lld",&x,&y,&k); 208 work1(x,y,k); 209 } 210 else if (mode==2) 211 { 212 scanf("%d%d",&x,&y); 213 printf("%lld\n",work2(x,y)); 214 } 215 else if (mode==3) 216 { 217 scanf("%d%lld",&x,&k); 218 work3(x,k); 219 } 220 else 221 { 222 scanf("%d",&x); 223 printf("%lld\n",work4(x)); 224 } 225 } 226 return 0; 227 } 228 /* 229 5 100 2 10000000 230 0 0 0 0 0 231 1 2 232 1 5 233 3 1 234 4 1 235 1 5 4 1 236 1 2 5 1 237 2 4 5 238 */