练手的模板题...成段更新,单点查询....点权不同于边权,稍微做一些处理就可以搞定了。
不自觉就用了线段树的lazy操作,不用复杂度似乎可以承受?
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAXN 103000
struct edge
{
int v,next;
}edge[MAXN*2];
int fa[MAXN],son[MAXN];
int p[MAXN],fp[MAXN];
int num[MAXN],dep[MAXN];
int top[MAXN],pos;
int head[MAXN],t;
void inti()
{
t=0;
memset(head,-1,sizeof(head));
pos=1;
memset(son,-1,sizeof(son));
}
void add(int u,int v)
{
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
void dfs1(int u,int d)
{
dep[u]=d;
num[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v!=fa[u])
{
fa[v]=u;
dfs1(v,d+1);
num[u]+=num[v];
if(son[u]==-1||num[v]>num[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int sp)
{
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1) return ;
dfs2(son[u],sp);
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v!=fa[u]&&v!=son[u])
dfs2(v,v);
}
}
struct node
{
int l,r,cover;
}data[MAXN*4];
void build(int l,int r,int k)
{
data[k].l=l;
data[k].r=r;
data[k].cover=0;
if(l==r) return ;
int mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
void updata(int k,int l,int r,int val)
{
if(data[k].l==l&&data[k].r==r)
{
data[k].cover+=val;
return ;
}
if(data[k].cover!=0)
{
data[k*2].cover+=data[k].cover;
data[k*2+1].cover+=data[k].cover;
data[k].cover=0;
}
int mid=(data[k].l+data[k].r)/2;
if(r<=mid) updata(k*2,l,r,val);
else if(l>mid) updata(k*2+1,l,r,val);
else
{
updata(k*2,l,mid,val);
updata(k*2+1,mid+1,r,val);
}
}
int query(int x,int k)
{
if(data[k].l==data[k].r&&data[k].l==x)
{
return data[k].cover;
}
if(data[k].cover!=0)
{
data[k*2].cover+=data[k].cover;
data[k*2+1].cover+=data[k].cover;
data[k].cover=0;
}
int mid=(data[k].l+data[k].r)/2;
if(x<=mid)
return query(x,k*2);
else
return query(x,k*2+1);
}
void change(int u,int v,int w)
{
int f1=top[u];
int f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(u,v);
}
updata(1,p[f1],p[u],w);
u=fa[f1];
f1=top[u];
}
if(dep[u]>dep[v]) swap(u,v);
updata(1,p[u],p[v],w);
}
int a[MAXN];
int main()
{
int n,m,q;
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
inti();
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int u,v,w;
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,1);
dfs2(1,1);
build(1,n,1);
char op[100];
while(q--)
{
scanf("%s",op);
if(op[0]=='I')
{
scanf("%d%d%d",&u,&v,&w);
change(u,v,w);
}
else if(op[0]=='D')
{
scanf("%d%d%d",&u,&v,&w);
change(u,v,-w);
}
else
{
scanf("%d",&u);
printf("%d\n",query(p[u],1)+a[u]);
}
}
}
return 0;
}