树链剖分裸题不解释
#include <vector> #include <cstdio> #include <climits> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int MAXN=1000010+2; struct HASH{ int u; HASH *next; HASH(){} HASH(int _u,HASH *_next):u(_u),next(_next){} }*table[MAXN],mem[2*MAXN]; typedef struct NODE{ int s,l,r,add; NODE *lchild,*rchild; NODE(){} NODE(int _l,int _r):l(_l),r(_r),s(0),add(0),lchild(0),rchild(0){} } *TREE; TREE root; int N,M,Q; int v[MAXN],c[MAXN],f[MAXN],d[MAXN],tab[MAXN],mark1[MAXN],mark2[MAXN],son[MAXN],cnt; char s; void Insert(int u,int v){ table[u]=&(mem[cnt++]=HASH(v,table[u]));} void DFS1(int u,int fa,int deep){ c[u]=1,f[u]=fa,d[u]=deep; for(HASH *p=table[u];p;p=p->next) if(p->u!=f[u]){ DFS1(p->u,u,deep+1); c[u]+=c[p->u]; if(son[u]==-1 || c[p->u]>c[son[u]]) son[u]=p->u; } } void DFS2(int u,int t){ tab[u]=t,mark1[u]=++cnt,mark2[cnt]=u; if(son[u]==-1) return; DFS2(son[u],t); for(HASH *p=table[u];p;p=p->next) if(p->u!=f[u] && p->u!=son[u]) DFS2(p->u,p->u); } void Pushup(TREE &x){ x->s=x->lchild->s+x->rchild->s;} void Pushdown(TREE &x,int m){ if(x->add){ x->lchild->s+=x->add*(m-(m>>1)); x->rchild->s+=x->add*(m>>1); x->lchild->add+=x->add,x->rchild->add+=x->add; x->add=0; } } void Build(TREE &x,int l,int r){ x=new NODE(l,r); if(l==r){ x->s=v[mark2[l]]; return; } int m=(l+r)>>1; Build(x->lchild,l,m),Build(x->rchild,m+1,r); Pushup(x); } void Update(TREE &x,int l,int r,int add){ if(l<=x->l && r>=x->r){ x->add+=add,x->s+=add*(x->r-x->l+1); return; } Pushdown(x,x->r-x->l+1); int m=(x->l+x->r)>>1; if(l<=m) Update(x->lchild,l,r,add); if(r>m) Update(x->rchild,l,r,add); Pushup(x); } void Change(int u,int v,int w){ while(tab[u]!=tab[v]){ if(d[tab[u]]<d[tab[v]]) swap(u,v); Update(root,mark1[tab[u]],mark1[u],w); u=f[tab[u]]; } if(d[u]>d[v]) swap(u,v); Update(root,mark1[u],mark1[v],w); } int Query(TREE &x,int p){ if(x->l==p && x->r==p) return x->s; Pushdown(x,x->r-x->l+1); int m=(x->l+x->r)>>1,ret=0; if(p<=m) ret=Query(x->lchild,p); else ret=Query(x->rchild,p); Pushup(x); return ret; } void Erase(TREE x){ if(!x) return; Erase(x->lchild),Erase(x->rchild); delete x; } int main(){ while(~scanf("%d %d %d",&N,&M,&Q)){ memset(son,-1,sizeof(son)); memset(table,0,sizeof(table)); for(int i=1;i<=N;i++) cin >> v[i]; for(int i=1,u,v;i<=M;i++){ cin >> u >> v; Insert(u,v),Insert(v,u); } cnt=0,DFS1(1,0,1); cnt=0,DFS2(1,1); Build(root,1,N); for(int i=1,C1,C2,K;i<=Q;i++){ cin >> s; if(s=='I'){ cin >> C1 >> C2 >> K; Change(C1,C2,K); } if(s=='D'){ cin >> C1 >> C2 >> K; Change(C1,C2,-K); } if(s=='Q'){ cin >> C1; cout << Query(root,mark1[C1]) << endl; } } Erase(root); } return 0; }