树链剖分模板+树状数组区间更新单点查询
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#pragma comment(linker, "/STACK:1024000000,1024000000");
using namespace std;
#define maxn 100005
int val[maxn];
int u[maxn],v[maxn],fir[maxn],nex[maxn],e_max;
int deep[maxn],fa[maxn],top[maxn],son[maxn],siz[maxn],pos[maxn];
int c[maxn];
int tot;
void init()
{
tot=1;
memset(c,0,sizeof c);
memset(siz,0,sizeof siz);
memset(son,-1,sizeof son);
memset(fa,-1,sizeof fa);
memset(fir,-1,sizeof fir);
e_max=0;
}
void add_edge(int s,int t)
{
int e=e_max++;
u[e]=s;
v[e]=t;
nex[e]=fir[s];
fir[s]=e;
}
int lowbit(int x)
{
return x&-x;
}
void update(int x,int val)
{
for(; x<=maxn; x+=lowbit(x)) c[x]+=val;
}
int query(int x)
{
int sum=0;
for(; x>0; x-=lowbit(x)) sum+=c[x];
return sum;
}
void dfs1(int k,int pre,int d)
{
fa[k]=pre;
deep[k]=d;
siz[k]++;
for(int i=fir[k]; ~i; i=nex[i])
{
int e=v[i];
if(e!=pre)
{
dfs1(e,k,d+1);
if(son[k]==-1||siz[e]>siz[son[k]]) son[k]=e;
siz[k]+=siz[e];
}
}
}
void dfs2(int k,int sp)
{
top[k]=sp;
pos[k]=tot++;
if(son[k]==-1) return ;
dfs2(son[k],sp);
for(int i=fir[k]; ~i; i=nex[i])
{
if(v[i]!=fa[k]&&v[i]!=son[k])
{
dfs2(v[i],v[i]);
}
}
}
void change(int s,int t,int c)
{
int f1=top[s],f2=top[t];
while(f1!=f2)
{
if(deep[f1]<deep[f2]) swap(f1,f2),swap(s,t);
update(pos[f1],c);
update(pos[s]+1,-c);
s=fa[f1];
f1=top[s];
}
if(deep[s]>deep[t]) swap(s,t);
update(pos[s],c);
update(pos[t]+1,-c);
}
int main()
{
int n,m,q;
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
init();
for(int i=1; i<=n; i++) scanf("%d",&val[i]);
for(int i=0; i<m; i++)
{
int a,b;
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
dfs1(1,-1,1);
dfs2(1,1);
for(int i=1; i<=n; i++) update(pos[i],val[i]),update(pos[i]+1,-val[i]);
while(q--)
{
char s[5];
scanf("%s",s);
if(s[0]=='Q')
{
int index;
scanf("%d",&index);
printf("%d\n",query(pos[index]));
}
else
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
if(s[0]=='D') c=-c;
change(l,r,c);
}
}
}
return 0;
}