题目链接
这题查找为单点查找,故可以用树状数组来维护。
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,q,tot,label,a[50010],Next[100010],head[100010],tree[100010],dep[50010],son[50010],size[50010],fa[50010];
int tid[50010],top[50010],f[50010];
bool visit[50010];
void swap(int &i,int &j)
{
int t=i;i=j;j=t;
}
void Add(int x,int y)
{
tot++;
Next[tot]=head[x];
head[x]=tot;
tree[tot]=y;
}
void dfs(int x,int father,int depth)
{
visit[x]=true;dep[x]=depth;son[x]=0;size[x]=1;fa[x]=father;
int maxsize=0 ;
for (int i=head[x];i;i=Next[i])
if (!visit[tree[i]])
{
dfs(tree[i],x,depth+1);
size[x]+=size[tree[i]];
if (size[tree[i]]>maxsize)
{
son[x]=tree[i];
maxsize=size[tree[i]];
}
}
}
void dfs1(int x,int ancestor)
{
visit[x]=true;top[x]=ancestor;label++;tid[x]=label;
if (son[x]!=0) dfs1(son[x],ancestor);
for (int i=head[x];i;i=Next[i])
if (!visit[tree[i]]) dfs1(tree[i],tree[i]);
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int d)
{
for (int i=x;i<=n;i+=lowbit(i)) f[i]+=d;
}
int get(int x)
{
int ans=0;
for (int i=x;i>=1;i-=lowbit(i)) ans+=f[i];
return ans;
}
int query_it(int x,int y)
{
return get(x);//单点查询,所以这里x=y;
}
void change_it(int x,int y,int d)
{
update(x,d);
update(y+1,-d);
}
int query(int x,int y)
{
int ans=0;
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=query_it(tid[top[x]],tid[x]);//此题查找是单点,故树状数组可以实现
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
ans+=query_it(tid[x],tid[y]);
return ans;
}
void change(int x,int y,int d)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
change_it(tid[top[x]],tid[x],d);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
change_it(tid[x],tid[y],d);
}
int main()
{
while (scanf("%d%d%d",&n,&m,&q)!=EOF)
{
tot=0;label=0;
for (int i=1;i<=n;i++) scanf("%d",&a[i]),f[i]=0,head[i]=0;
int x,y,z;
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
Add(x,y);Add(y,x);
}
for (int i=1;i<=n;i++) visit[i]=false;
dfs(1,0,1);
for (int i=1;i<=n;i++) visit[i]=false;
dfs1(1,1);
for (int i=1;i<=n;i++) change_it(tid[i],tid[i],a[i]);
char s[5];
for (int i=1;i<=q;i++)
{
scanf("%s",s);
if (s[0]=='Q')
{
scanf("%d",&x);
printf("%d\n",query(x,x));
}
if (s[0]=='I')
{
scanf("%d%d%d",&x,&y,&z);
change(x,y,z);
}
if (s[0]=='D')
{
scanf("%d%d%d",&x,&y,&z);
change(x,y,-z);
}
}
}
return 0;
}