树剖模板(洛谷P3384 【模板】树链剖分)(树链剖分,树状数组,树的dfn序)
2018-08-12 17:52
525 查看
洛谷题目传送门
仍然是一个板子。
不过蒟蒻去学了一下BIT维护区间修改区间求和,常数果真十分优秀
设数列为\(a_i\),差分数组\(d_ i=a_ i-a_ {i-1}\),前缀和\(s_i=\sum\limits_ {j=1}^ia_ j\)
显然有\(a_ i=\sum\limits_ {j=1}^id_ j\)
于是大力展开得到
\[s_i=\sum\limits_{j=1}^i(i-j+1)d_j\]
\[s_i=(i+1)\sum\limits_{i=1}^jd_j-\sum\limits_{j=1}^ijd_j\]
用BIT维护\(d_i\)和\(id_i\)的前缀和即可。
仍然是一个板子。
不过蒟蒻去学了一下BIT维护区间修改区间求和,常数果真十分优秀
设数列为\(a_i\),差分数组\(d_ i=a_ i-a_ {i-1}\),前缀和\(s_i=\sum\limits_ {j=1}^ia_ j\)
显然有\(a_ i=\sum\limits_ {j=1}^id_ j\)
于是大力展开得到
\[s_i=\sum\limits_{j=1}^i(i-j+1)d_j\]
\[s_i=(i+1)\sum\limits_{i=1}^jd_j-\sum\limits_{j=1}^ijd_j\]
用BIT维护\(d_i\)和\(id_i\)的前缀和即可。
#include<cstdio> #define RG register #define R RG int #define G if(++ip==ie)fread (ip=ibuf,1,L,stdin) #define P(C) *op=C;if(++op==oe)fwrite(op=obuf,1,L,stdout) typedef long long LL; const int N=1e5+9,M=N<<1,L=1<<19; char ibuf[L],*ie=ibuf+L,*ip=ie-1,obuf[L],*oe=obuf+L,*op=obuf; int YL,n,p,a ,he ,ne[M],to[M],f ,s ,id ,pr ,dep ,top ,d ,e ; inline int in(){ G;while(*ip<'-')G; R x=*ip&15;G; while(*ip>'-'){(x*=10)+=*ip&15;G;} return x; } void out(R x){ if(x>9)out(x/10); P(x%10|'0'); } inline void swap(R&x,R&y){ R z=x;x=y;y=z; } void dfs1(R x,R y){ s[x]=1; dep[x]=dep[f[x]=y]+1; for(R i=he[x];i;i=ne[i]) if(to[i]!=y)dfs1(to[i],x); s[y]+=s[x]; if(s[pr[y]]<s[x])pr[y]=x; } void dfs2(R x,R y){ top[x]=y; d[id[x]=++p]=a[x]; if(!pr[x])return; dfs2(pr[x],y); for(R i=he[x];i;i=ne[i]) if(!id[to[i]])dfs2(to[i],to[i]); } inline void mdf(R*d,R i,R v){ for(;i<=n;i+=i&-i)(d[i]+=v)%=YL; } inline void upd(R l,R r,R v){ mdf(d,l,v);mdf(e,l,(LL)v*l%YL);v=YL-v; mdf(d,r,v);mdf(e,r,(LL)v*r%YL); } inline int qry(R*d,R i){ R v=0; for(;i;i-=i&-i)(v+=d[i])%=YL; return v; } inline int ask(R l,R r){ return (((LL)(r+1)*qry(d,r)-qry(e,r)-(LL)(l+1)*qry(d,l)+qry(e,l))%YL+YL)%YL; } int main(){ n=in();R m=in(),rt=in(),i,x,y,z,ans;YL=in(); for(i=1;i<=n;++i)a[i]=in(); for(i=1;i<n;++i){ x=in();y=in(); ne[++p]=he[x];to[he[x]=p]=y; ne[++p]=he[y];to[he[y]=p]=x; } p=0;dfs1(rt,0);dfs2(rt,rt); for(i=n;i;--i){ d[i]=((d[i]-d[i-1])%YL+YL)%YL; e[i]=(LL)i*d[i]%YL; } for(i=1;i<=n;++i){ if((x=i+(i&-i))>n)continue; (d[x]+=d[i])%=YL;(e[x]+=e[i])%=YL; } while(m--) switch(in()){ case 1:x=in();y=in();z=in()%YL; for(;top[x]!=top[y];x=f[top[x]]){ if(dep[top[x]]<dep[top[y]])swap(x,y); upd(id[top[x]],id[x]+1,z); } if(dep[x]<dep[y])swap(x,y); upd(id[y],id[x]+1,z); break; case 2:x=in();y=in();ans=0; for(;top[x]!=top[y];x=f[top[x]]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=ask(id[top[x]]-1,id[x]); } if(dep[x]<dep[y])swap(x,y); out((ans+ask(id[y]-1,id[x]))%YL);P('\n'); break; case 3:x=in();z=in()%YL; upd(id[x],id[x]+s[x],z); break; case 4:x=in(); out(ask(id[x]-1,id[x]+s[x]-1));P('\n'); } fwrite(obuf,1,op-obuf,stdout); return 0; }
相关文章推荐
- 洛谷 P3384 【模板】树链剖分
- 洛谷 P3384 【模板】树链剖分(指针版)
- 洛谷 P3384 【模板】树链剖分
- 洛谷 P3384 【模板】树链剖分
- 洛谷P3384【模板】树链剖分 (树链剖分)
- 洛谷P3384 【模板】树链剖分
- 【洛谷P3384】【模板】树链剖分
- 洛谷 P3384 【模板】树链剖分
- 洛谷树剖模板题 P3384 | 树链剖分
- 洛谷P3384【模板】树链剖分
- 洛谷——P3384 【模板】树链剖分
- 树链剖分 模板 洛谷P3384
- 洛谷P3384 【模板】树链剖分
- 洛谷P3384 【模板】树链剖分
- AC日记——【模板】树链剖分 洛谷 P3384
- 【树链剖分】洛谷P3384树剖模板
- 【洛谷】3384 【模板】树链剖分
- P3384 【模板】树链剖分
- 洛谷——P3368 【模板】树状数组 2
- 洛谷3384:【模板】树链剖分——题解