BZOJ4034 树上操作

mac2022-06-30  146

目录

BZOJ4034 树上操作题解code

BZOJ4034 树上操作

题目传送门

题解

裸的树剖,写的时候注意细节即可。

code

#include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;} template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x+'0');} template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');} template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);} /*================Header Template==============*/ #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin); const int maxn=2e5+500; #define ls(o) o<<1 #define rs(o) (o<<1|1) int n,m,tot; ll a[maxn],val[maxn]; int fa[maxn],deep[maxn],sz[maxn],heav[maxn],idx[maxn],top[maxn],head[maxn]; struct edge { int to,nxt; }E[maxn<<2]; /*==================Define Area================*/ namespace SegmentTree { struct node { int l,r,sz; ll v; ll lazy; }t[maxn<<3]; void Update(int o) { t[o].v=t[ls(o)].v+t[rs(o)].v; } void Pushdown(int o) { if(!t[o].lazy) return; t[ls(o)].v+=t[ls(o)].sz*t[o].lazy;t[rs(o)].v+=t[rs(o)].sz*t[o].lazy; t[ls(o)].lazy+=t[o].lazy;t[rs(o)].lazy+=t[o].lazy; t[o].lazy=0; } void Build(int o,int l,int r) { t[o].l=l;t[o].r=r;t[o].sz=r-l+1; if(l==r) { t[o].v=a[l]; return ; } int mid=(l+r)>>1; Build(ls(o),l,mid); Build(rs(o),mid+1,r); Update(o); return ; } void IntervalAdd(int o,int l,int r,ll v) { if(l<=t[o].l&&t[o].r<=r) { t[o].v+=t[o].sz*v; t[o].lazy+=v; return ; } int mid=(t[o].l+t[o].r)>>1; Pushdown(o); if(mid>=l) IntervalAdd(ls(o),l,r,v); if(mid<r) IntervalAdd(rs(o),l,r,v); Update(o); return ; } ll IntervalSum(int o,int l,int r) { if(l<=t[o].l&&t[o].r<=r) return t[o].v; int mid=(t[o].l+t[o].r)>>1; Pushdown(o); ll ans=0; if(mid>=l) ans+=IntervalSum(ls(o),l,r); if(mid<r) ans+=IntervalSum(rs(o),l,r); return ans; } } using namespace SegmentTree; namespace poufen { void dfs1(int o,int ff,int dep) { fa[o]=ff;deep[o]=dep; sz[o]=1; int mxson=-1; for(int i=head[o];~i;i=E[i].nxt) { int to=E[i].to; if(to==ff) continue; dfs1(to,o,dep+1); if(sz[to]>mxson) mxson=sz[to],heav[o]=to; sz[o]+=sz[to]; } return ; } int cnt=0; void dfs2(int o,int topp) { idx[o]=++cnt; a[cnt]=val[o]; top[o]=topp; if(!heav[o]) return ; dfs2(heav[o],topp); for(int i=head[o];~i;i=E[i].nxt) { int to=E[i].to; if(!idx[to]) dfs2(to,to); } } ll TreeSum(int x,int y) { ll ans=0; while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); ans+=IntervalSum(1,idx[top[x]],idx[x]); x=fa[top[x]]; } if(deep[x]>deep[y]) swap(x,y); ans+=IntervalSum(1,idx[x],idx[y]); return ans; } } using namespace poufen; void addedge(int u,int v) { E[++tot].to=v;E[tot].nxt=head[u];head[u]=tot; E[++tot].to=u;E[tot].nxt=head[v];head[v]=tot; } signed main() { memset(head,-1,sizeof head); read(n);read(m); for(int i=1;i<=n;i++) { read(val[i]); } for(int i=1,u,v;i<n;i++) { read(u);read(v); addedge(u,v); } dfs1(1,1,0); dfs2(1,1); Build(1,1,n); for(int i=1,opt;i<=m;i++) { read(opt); if(opt==1) { int x; ll a; read(x);read(a); IntervalAdd(1,idx[x],idx[x],a); } if(opt==2) { int x; ll a; read(x);read(a); IntervalAdd(1,idx[x],idx[x]+sz[x]-1,a); } if(opt==3) { int x; read(x);; ll ans=TreeSum(x,1); printf("%lld\n",ans); } } return 0; } /* 5 5 1 2 3 4 5 1 2 1 4 2 3 2 5 3 3 1 2 1 3 5 2 1 2 3 3 */

转载于:https://www.cnblogs.com/Apocrypha/p/9435091.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)