3 2 5 1 2 3 2 1 2 3 I 1 3 5 Q 2 D 1 2 2 Q 1 Q 3
7 4 8
树链剖分模板题
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define MAX 50005 #define mod 10000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; struct edge { int v,next; } e[MAX*4]; int a[MAX],tot,head[MAX],dep[MAX],sum[MAX*4],lazy[MAX*4]; int pre[MAX],siz[MAX],son[MAX],top[MAX],intr[MAX],id[MAX*4]; void addedge(int u,int v) { e[tot].v=v; e[tot].next=head[u]; head[u]=tot++; } void Swap(int &a,int &b) { int t; t=a,a=b,b=t; } void dfs(int u,int fa,int d) { dep[u]=d; pre[u]=fa; siz[u]=1; for(int i=head[u]; i!=-1; i=e[i].next) { int v=e[i].v; if(v!=fa) { dfs(v,u,d+1); siz[u]+=siz[v]; if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v; } } } int len; void DFS(int u,int tp) { top[u]=tp; intr[u]=len++; id[intr[u]]=u; if(son[u]!=-1) DFS(son[u],tp); else return ; for(int i=head[u]; i!=-1; i=e[i].next) { int v=e[i].v; if(v!=son[u]&&v!=pre[u]) DFS(v,v); } } void pushup(int u) { sum[u]=max(sum[ul],sum[ur]); } void pushdown(int u,int x) { lazy[ul]+=lazy[u]; lazy[ur]+=lazy[u]; sum[ul]+=(x-(x>>1))*lazy[u]; sum[ur]+=(x>>1)*lazy[u]; lazy[u]=0; } void build(int l,int r,int u) { lazy[u]=0; if(l==r) { sum[u]=a[id[l]]; return ; } int mid=(l+r)>>1; build(l,mid,ul); build(mid+1,r,ur); pushup(u); } void updata(int s,int e,int l,int r,int x,int u) { if(s<=l&&r<=e) { lazy[u]+=x; sum[u]+=x*(r-l+1); return ; } if(lazy[u]) pushdown(u,r-l+1); int mid=(l+r)>>1; if(s<=mid) updata(s,e,l,mid,x,ul); if(e>mid) updata(s,e,mid+1,r,x,ur); pushup(u); } int query(int pos,int l,int r,int u) { if(l==r) { return sum[u]; } if(lazy[u]) pushdown(u,r-l+1); int mid=(l+r)>>1; if(pos<=mid) return query(pos,l,mid,ul); else return query(pos,mid+1,r,ur); pushup(u); } void change(int s,int e,int x) { while(top[s]!=top[e]) { if(dep[top[s]]<dep[top[e]]) Swap(s,e); updata(intr[top[s]],intr[s],1,len,x,1); s=pre[top[s]]; } if(dep[s]>dep[e]) Swap(s,e); updata(intr[s],intr[e],1,len,x,1); } void init() { tot=0; len=1; CLR(head,-1); CLR(son,-1); } int main() { int n,m,p,u,v,w; char c[20]; while(scanf("%d%d%d",&n,&m,&p)!=EOF) { init(); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=m; i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs(1,0,0); DFS(1,1); build(1,len,1); for(int i=1; i<=p; i++) { scanf("%s",&c); if(c[0]=='Q') scanf("%d",&u),printf("%d\n",query(intr[u],1,len,1)); else { scanf("%d%d%d",&u,&v,&w); if(c[0]=='I') change(u,v,w); else change(u,v,-w); } } } return 0; }