题目链接
第一道链剖的题目,从早晨七点到图书馆开始写,写了一上午,才把树链剖开。
晚上开始边看明日之子的直播听他们唱歌,边维护线段树(下午做了一场多校)
debug了无数次之后,终于写对了。
还是挺开心的,因为代码都是自己写的。
题意:给一棵树,每个节点都有一个权值。
有三种操作:
I:x y v 将x到y路径中的所有节点的权值都加上v
D:x y v 将x到y路径中的所有节点的权值都减去v
Q:x 查询x节点的权值
参考代码|
#include
#include
#include
#include
#include
#include
#define memset(a,v) memset(a,v,sizeof(a))
#define max(a,b) (a>b?a:b)
#define min(a,b) (asiz[son[u]])
son[u]=v;
}
}
}
inline void dfs2(int u,int t)
{
top[u]=t;
pos[u]=dpos;
repos[dpos]=u;
dpos++;
if(son[u]==-1)
return;
dfs2(son[u],t);
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v!=son[u]&&v!=father[u])
dfs2(v,v);
}
}
void add_edge(int u,int v)
{
edge[cnt]=node(v,head[u]);
head[u]=cnt++;
}
struct Node
{
int l,r,data,lazy;
}tree[4*MAXL+50];
void PushUp(int k)
{
tree[k].data=tree[k<<1].data+tree[k<<1|1].data;
}
void PushDown(int k)
{
if(!tree[k].lazy) return;
tree[k<<1].lazy+=tree[k].lazy;
tree[k<<1|1].lazy+=tree[k].lazy;
tree[k<<1].data+=tree[k].lazy*(tree[k<<1].r-tree[k<<1].l+1);
tree[k<<1|1].data+=tree[k].lazy*(tree[k<<1|1].r-tree[k<<1|1].l+1);
tree[k].lazy=0;
}
void build(int l,int r,int k)
{
tree[k].l=l,tree[k].r=r,tree[k].lazy=0;
if(l==r)
{
tree[k].data=a[repos[l]];
return;
}
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
PushUp(k);
}
void update(int ul,int ur,int v,int k)
{
if(tree[k].l>=ul&&tree[k].r<=ur)
{
tree[k].data+=(tree[k].r-tree[k].l+1)*v;
tree[k].lazy+=v;
return;
}
PushDown(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(ul<=mid)
update(ul,ur,v,k<<1);
if(ur>mid)
update(ul,ur,v,k<<1|1);
PushUp(k);
}
void change(int u,int v,int val)
{
int fu=top[u],fv=top[v];
int ans=0;
while(fu!=fv)
{
if(depth[fu]depth[v]) swap(u,v);
update(pos[u],pos[v],val,1);
}
int ans;
void query(int qpoint,int k)
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].data;
return;
}
PushDown(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(qpoint<=mid)
query(qpoint,k<<1);
else
query(qpoint,k<<1|1);
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&q))
{
init();
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs1(1,0,0);
dfs2(1,1);
build(1,n,1);
while(q--)
{
char ch[2];
scanf("%s",ch);
if(ch[0]=='Q')
{
int x;
scanf("%d",&x);
query(pos[x],1);
printf("%d\n",ans);
}
if(ch[0]=='I')
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
change(x,y,v);
}
if(ch[0]=='D')
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
v=-v;
change(x,y,v);
}
}
}
}