HDU 3966 Aragorn's Story(树链剖分+线段树区间更改+单点查询)

题目:Aragorn’s Story

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]));
            }
        }
    }
}
发布了221 篇原创文章 · 获赞 16 · 访问量 9744

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/104120073