树剖代码求助

P3384 【模板】重链剖分/树链剖分

Binah_cyc @ 2024-01-18 21:49:41

rt,过不了样例求助

#include <bits/stdc++.h>
using namespace std;
//#define int long long
const int N=1e5+5;
int mod;
int n,m,r,sum[N];
int f[N],son[N],sze[N],deep[N],id[N],top[N],a[N],cnt;
int tot,head[N];
struct Node
{
    int nxt,to;
} edge[N<<1];
struct SegementTree
{
    int l,r;
    int ans,add;
} t[N<<2];
void add(int x,int y)
{
    edge[++tot]=(Node)
    {
        head[x],y
    };
    head[x]=tot;
}
void dfs1(int now,int fa,int dep)
{
    deep[now]=dep;
    f[now]=fa;
    sze[now]=1;
    int t=-1;
    for(int i=head[now]; i; i=edge[i].nxt)
    {
        if(edge[i].to==fa) continue;
        dfs1(edge[i].to,now,dep+1);
        sze[now]+=sze[edge[i].to];
        if(sze[edge[i].to]>t) t=sze[edge[i].to],son[now]=edge[i].to;
    }
}
void dfs2(int now,int ffa)
{
    id[now]=++cnt;
    a[cnt]=sum[now];
    top[cnt]=ffa;
    if(!son[now]) return ;
    dfs2(son[now],ffa);
    for(int i=head[now]; i; i=edge[i].nxt)
    {
        if(edge[i].to==son[now]||edge[i].to==f[now]) continue;
        dfs2(edge[i].to,edge[i].to);
    }
}
void build(int l,int r,int p)
{
    t[p].l=l;
    t[p].r=r;
    if(l==r)
    {
        t[p].ans=a[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,p*2);
    build(mid+1,r,p*2+1);
    t[p].ans=t[p*2].ans+t[p*2+1].ans;
    return ;
}
void spread(int p)
{
    if(t[p].add)
    {
        t[p*2].ans=(t[p*2].ans+(t[p*2].r-t[p*2].l+1)*t[p].add)%mod;
        t[p*2+1].ans=(t[p*2+1].ans+(t[p*2+1].r-t[p*2+1].l+1)*t[p].add)%mod;
        t[p*2].add+=t[p].add;
        t[p*2+1].add+=t[p].add;
        t[p].add=0;
    }
    return ;
}
void change(int l,int r,int k,int p)
{
    if(l<=t[p].l&&r>=t[p].r)
    {
        t[p].ans=(t[p].ans+(t[p].r-t[p].l+1)*k)%mod;
        t[p].add+=k;
        return ;
    }
    spread(p);
    int mid=(t[p].l+t[p].r)>>1;
    if(l<=mid) change(l,r,k,p*2);
    if(r>mid) change(l,r,k,p*2+1);
    t[p].ans=t[p*2].ans+t[p*2+1].ans;
    return ;
}
int ask(int l,int r,int p)
{
    if(l<=t[p].l&&t[p].r<=r) return t[p].ans;
    spread(p);
    int sum=0,mid=(t[p].l+t[p].r)>>1;
    if(l<=mid) sum+=ask(l,r,p*2);
    if(r>mid) sum+=ask(l,r,p*2+1);
    return sum;
}
void changeroad(int x,int y,int num)
{
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        change(id[top[x]],id[x],num,1);
        x=f[top[x]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    change(id[x],id[y],num,1);
}
int askroad(int x,int y)
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        ans=(ans+ask(id[top[x]],id[x],1))%mod;
        x=f[top[x]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    return (ans+ask(id[x],id[y],1))%mod;
}
void changetree(int x,int num)
{
    change(id[x],id[x]+sze[x]-1,num,1);
    return ;
}
int asktree(int x)
{
    return ask(id[x],id[x]+sze[x]-1,1);
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>r>>mod;
    int x,y;
    for(int i=1; i<=n; i++) cin>>sum[i];
    for(int i=1; i<n; i++)
    {
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    dfs1(r,0,1);
    dfs2(r,r);
    build(1,n,1);
    while(m--)
    {
        int op,x,y,z;
        cin>>op;
        if(op==1)
        {
            cin>>x>>y>>z;
            changeroad(x,y,z%mod);
        }
        else if(op==2)
        {
            cin>>x>>y;
            cout<<askroad(x,y)<<endl;
        }
        else if(op==3)
        {
            cin>>x>>z;
            changetree(x,z);
        }
        else if(op==4)
        {
            cin>>x;
            cout<<asktree(x)<<endl;
        }
//      cout<<askroad(1,1)<<' '<<askroad(3,3)<<' '<<askroad(4,4)<<' '<<askroad(5,5)<<" "<<endl;
    }
//  for(int i=1;i<=n;i++) cout<<i<<' '<<"deep:"<<deep[id[i]]<<' '<<"f:"<<f[id[i]]<<' '<<"id:"<<id[i]<<' '<<"son:"<<son[id[i]]<<' '<<"sum:"<<sum[id[i]]<<' '<<"sze:"<<sze[id[i]]<<' '<<"top:"<<top[id[i]]<<'\n';
    return 0;
}

by sunkuangzheng @ 2024-01-18 21:58:24

@Binah_cyc top_cnt = ffa 改成 top_now = ffa 试试?


by Binah_cyc @ 2024-01-18 22:04:26

@sunkuangzheng 谢谢,已关!


|