2020/1/30/11:30
由于hdu的oj在维修,我的代码提交不了,所以很遗憾,我现在写的代码不能确认其正确性,有点难受。其实这个题是一个简单的树剖板题,但是我敲完代码后,准备交,但是由于以上原因,交不了,我就去搜了题解,看了正解和我的代码的懒标部分不太一样,所以我不知道我的代码的正确性,我也测了一些样例感觉没什么问题,所以就先放着再说
2020/1/31/10:28
今天早上Hdu恢复正常,我测了我的代码,没有一发过,MLE了,然后我就开始debug了,因为树剖的dfs1()和dfs2()过程都是赋值的过程,我并没有清空,但是在重儿子的标记上面出现了问题,如果不清空重儿子数组,那么一开始有节点的重儿子,在下一次成为没有节点的重儿子的时候,就会出现问题, 在dfs2()的时候按照重儿子dfs2()的过程中,就会到没有重儿子的节点上继续dfs2(),从而导致MLE,所以必须清空数组
son[ ]
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e5+5;
int dfn[maxn],sizx[maxn],deep[maxn],top[maxn],pre[maxn];
int head[maxn],cnx,n,m,q,w[maxn],son[maxn],cnt,a[maxn];
struct node
{
int to,nex;
} edge[maxn];
void add(int u,int v)
{
edge[cnx].to=v;
edge[cnx].nex=head[u];
head[u]=cnx++;
}
void dfs1(int u,int fa)
{
pre[u]=fa;
deep[u]=deep[fa]+1;
sizx[u]=1;
int maxson=-1;
for(int i=head[u]; ~i; i=edge[i].nex)
{
int v=edge[i].to;
if(v!=fa)
{
dfs1(v,u);
sizx[u]+=sizx[v];
if(sizx[v]>maxson)
{
son[u]=v;
maxson=sizx[v];
}
}
}
}
void dfs2(int u,int t)
{
dfn[u]=++cnt;
top[u]=t;
w[cnt]=a[u];
if(!son[u])
return;
dfs2(son[u],t);
for(int i=head[u]; ~i; i=edge[i].nex)
{
int v=edge[i].to;
if(v==pre[u]||v==son[u])
continue;
dfs2(v,v);
}
}
struct yzj
{
int l,r,p,lazy;
} tr[maxn<<2];
void pushdown(int k)
{
if(tr[k].lazy)
{
tr[k<<1].lazy+=tr[k].lazy;
tr[k<<1|1].lazy+=tr[k].lazy;
tr[k<<1].p+=tr[k].lazy;
tr[k<<1|1].p+=tr[k].lazy;
tr[k].lazy=0;
}
}
void build(int k,int l,int r)
{
tr[k].l=l,tr[k].r=r,tr[k].lazy=0;
if(l==r)
{
tr[k].p=w[l];
return ;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void modify(int k,int l,int r,int z)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
tr[k].lazy+=z;
tr[k].p+=z;
return ;
}
pushdown(k);
int mid=tr[k].l+tr[k].r>>1;
if(mid>=r)
{
modify(k<<1,l,r,z);
}
else if(mid<l)
{
modify(k<<1|1,l,r,z);
}
else
{
modify(k<<1,l,mid,z);
modify(k<<1|1,mid+1,r,z);
}
}
void opt(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
swap(x,y);
modify(1,dfn[top[x]],dfn[x],z);
x=pre[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
modify(1,dfn[x],dfn[y],z);
}
int query(int k,int pos)
{
if(tr[k].l==tr[k].r)
{
return tr[k].p;
}
pushdown(k);
int mid=tr[k].l+tr[k].r>>1;
if(mid>=pos)
{
return query(k<<1,pos);
}
else
{
return query(k<<1|1,pos);
}
}
int main()
{
while(~scanf("%d %d %d",&n,&m,&q))
{
memset(head,-1,sizeof(head));
memset(son,0,sizeof(son));
cnx=cnt=0;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
int u,v;
for(int i=1; i<=m; i++)
{
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
char s[5];
while(q--)
{
scanf("%s",s);
int x,y,z;
if(s[0]=='I')
{
scanf("%d %d %d",&x,&y,&z);
opt(x,y,z);
}
else if(s[0]=='D')
{
scanf("%d %d %d",&x,&y,&z);
opt(x,y,-z);
}
else
{
int pos;
scanf("%d",&pos);
printf("%d\n",query(1,dfn[pos]));
}
}
}
}