萌新刚学树剖边权转点权,WA 47pts,求助

P3038 [USACO11DEC] Grass Planting G

Eason2009 @ 2022-07-16 17:05:08

#include<bits/stdc++.h>
#define int long long
#define maxn 400005
using namespace std;
int n,m,head[maxn],to[maxn],nex[maxn],tree[maxn],lazy[maxn],top[maxn],siz[maxn],son[maxn],dep[maxn],fa[maxn],id[maxn],tot;
void add(int u,int v)
{
    tot++;
    to[tot]=v;
    nex[tot]=head[u];
    head[u]=tot;
    return;
}
void dfs1(int u,int f,int d)
{
    int maxx=0;
    dep[u]=d;
    fa[u]=f;
    siz[u]=1;
    for(int i=head[u];i;i=nex[i])
    {
        int v=to[i];
        if(v==f) continue;
        dfs1(v,u,d+1);
        siz[u]+=siz[v];
        if(siz[v]>maxx) maxx=siz[v],son[u]=v;
    }
    return;
}
void dfs2(int u,int topp)
{
    top[u]=topp;
    id[u]=++tot;
    if(!son[u]) return;
    dfs2(son[u],topp);
    for(int i=head[u];i;i=nex[i])
    {
        int v=to[i];
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
    return;
}
void pushdown(int now,int len)
{
    lazy[now*2]+=lazy[now];
    lazy[now*2+1]+=lazy[now];
    tree[now*2]+=lazy[now]*(ceil(len/2));
    tree[now*2+1]+=lazy[now]*len/2;
    lazy[now]=0;
    return;
}
void pushup(int now)
{
    tree[now]=tree[now*2]+tree[now*2+1];
    return;
}
void upd(int now,int l,int r,int ql,int qr)
{
    if(l>r||r<ql||l>qr) return;
    if(l>=ql&&r<=qr)
    {
        tree[now]+=r-l+1;
        lazy[now]++;
        return;
    }
    else
    {
        int mid=l+r>>1;
        if(lazy[now]) pushdown(now,r-l+1);  
        if(ql<=mid) upd(now*2,l,mid,ql,qr);
        if(qr>mid) upd(now*2+1,mid+1,r,ql,qr);
    }
    pushup(now);
    return;
}
void update(int u,int v)
{
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        upd(1,1,n,id[top[u]],id[u]);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    if(u!=v) upd(1,1,n,id[u]+1,id[v]);
    return;
}
int qry(int now,int l,int r,int ql,int qr)
{
    if(l>r||r<ql||l>qr) return 0;
    if(l>=ql&&r<=qr) return tree[now];
    int mid=l+r>>1;
    if(lazy[now]) pushdown(now,r-l+1);
    return qry(now*2,l,mid,ql,qr)+qry(now*2+1,mid+1,r,ql,qr);
}
int query(int u,int v)
{
    int ans=0;
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        ans+=qry(1,1,n,id[top[u]],id[u]);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    if(u!=v) ans+=qry(1,1,n,id[u]+1,id[v]);
    return ans;
}
signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n-1;i++)
    {
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    tot=0;
    dfs1(1,0,1);
    dfs2(1,1);
    while(m--)
    {
        string op;
        int u,v;
        cin>>op>>u>>v;
        if(op=="P") update(u,v);
        else
        {
            cout<<query(u,v)<<endl;
        }
    }
    return 0;
}


by xinggancaixukun @ 2022-07-16 17:11:31

@Eason2009 建议数组开 8 \times 10^5


by Eason2009 @ 2022-07-16 17:13:57

@Xaga 还是47分


by 南阳刘子骥 @ 2022-07-17 08:27:26

@Eason2009 是线段树pushdown()的问题

我改成下面这个样子就可以了

void pushdown(int now, int l, int r)
{
    int mid = (l + r) >> 1;
    lazy[now * 2] += lazy[now];
    lazy[now * 2 + 1] += lazy[now];
    tree[now * 2] += lazy[now] * (mid - l + 1);
    tree[now * 2 + 1] += lazy[now] * (r - mid);
    lazy[now] = 0;
    return;
}

提交寄录


by Eason2009 @ 2022-07-17 08:29:27

@南阳刘子骥 已经AC了,但还是谢谢


|