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 8Hint1.The number of enemies may be negative. 2.Huge input, be careful.
实在是受不了邝斌那种非得用单点更新的函数写区间更新的写法,太不好理解了,自己在这个基础上改了,mark一下,以后比赛的时候要打印
一个小错误是如果初始值不加入树中,最后求再加进去的时候下标不要换成p[u]!所以说,自己写示例是多么重要
/************ hdu3966 2016.2.2 1014MS 9792K 2876 B G++ ************/ #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50005; struct edge{ int to,next; }edge[maxn*2]; int head[maxn],tot; int top[maxn];//表示此节点所在重链的顶端节点 int fa[maxn];//父节点 int deep[maxn];//单纯深度,不包括点权和边权 int num[maxn];//以此节点为根的子树节点数 int p[maxn];//此点对应的位置 int fp[maxn];//与上相反 int son[maxn];//重儿子 int pos; int c[maxn],n; void init() { tot=0; memset(head,-1,sizeof(head)); pos=1;//树状数组的 memset(son,-1,sizeof(son)); memset(c,0,sizeof(c)); } void addedge(int u,int v) { edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++; } void dfs1(int u,int pre,int d)//fa deep num son { deep[u]=d; fa[u]=pre; num[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v!=pre) { dfs1(v,u,d+1); num[u]+=num[v]; if(son[u]==-1||num[v]>num[son[u]]) son[u]=v; } } } void getpos(int u,int sp)//top p { top[u]=sp; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1) return; getpos(son[u],sp); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v!=son[u]&&v!=fa[u]) getpos(v,v); } } int lowbit(int x) { return x&(-x); } int sum(int i) { int s=0; while(i<=n) { s+=c[i]; i+=lowbit(i); } return s; } void add(int i,int val) { while(i>0) { c[i]+=val; i-=lowbit(i); } } void change(int u,int v,int val) { int f1=top[u],f2=top[v]; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } add(p[u],val); add(p[f1]-1,-val); u=fa[f1]; f1=top[u]; } if(deep[u]>deep[v]) swap(u,v); add(p[u]-1,-val); add(p[v],val); } int a[maxn]; int main() { // freopen("cin.txt","r",stdin); int M,P; while(~scanf("%d%d%d",&n,&M,&P)) { int u,v; int C1,C2,K; char op[2]; init(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); while(M--) { scanf("%d%d",&u,&v); addedge(u,v);addedge(v,u); } dfs1(1,0,0); getpos(1,1); while(P--) { scanf("%s",op); if(op[0]=='Q') { scanf("%d",&u); // printf("sum=%d ",sum(p[u])); printf("%d\n",sum(p[u])+a[u]); } else { scanf("%d%d%d",&C1,&C2,&K); if(op[0]=='D') K=-K; change(C1,C2,K); } } } return 0; }