蒟蒻刚学树剖样例未过求调
查看原帖
蒟蒻刚学树剖样例未过求调
388414
comcopy楼主2022/7/20 20:50

RT

自己本地调了一下发现是输入的第五个数存入的时候出了问题,查询出来的结果是7,但是蒟蒻萌新找不到挂在哪里了,所以求大佬调调QwQ

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+10;


int he[M],dep[M],fa[M],sz[M],id[M],w[M],top[M];
int a[M];
int mod;

vector<int> v[M];

int dfs1(int u,int d)
{
    dep[u]=d;
    he[u]=-1,sz[u]=1;
    vector<int>::iterator it;
    for(it=v[u].begin();it!=v[u].end();++it)
        {
            int to=*it;
            if(to==fa[u]) continue;
            fa[to]=u;
                sz[u]+=dfs1(to,d+1);
                if(he[u]==-1 || sz[he[u]]<sz[to]) 
                    he[u]=to;
        }
    return sz[u];
}


int cnt;
void dfs2(int u,int t)
{
    id[u]=++cnt;
    w[cnt]=a[u];
    top[u]=t;
    if(he[u]==-1 || !he[u]) return;
    dfs2(he[u],t);
    vector<int>::iterator i;
    for(i=v[u].begin();i!=v[u].end();++i)
        {
            int to=*i;
            if(to!=fa[u] && to!=he[u])
                dfs2(to,to);
        }
    return;
}

//树链剖分部分完结!!


struct tre
{
    int b[M<<2],lz[M<<2];

    void build(int l,int r,int now)
    {
        if(l==r)
            {
                b[now]=a[l];
                return;
            }
        int m=((r-l)>>1)+l;
        build(l,m,now<<1);
        build(m+1,r,now<<1|1);
        b[now]=(b[now<<1]+b[now<<1|1]) ;
        return;
    }


    inline void pushdown(int x,int len)
    {
        lz[x<<1]+=lz[x],lz[x<<1|1]+=lz[x];
        a[x<<1]+=lz[x]*(len-(len>>1));
        a[x<<1|1]+=lz[x]*(len>>1);
        lz[x]=0;
        return;
    }

    inline int query(int l,int r,int nl,int nr,int now)
    {
        if(l<=nl && nr<=r)
            {
                return b[now];
            }
        if(lz[now]) pushdown(now,r-l+1);
        int m=((nr-nl)>>1)+nl;
        int ans=0;
        if(l<=m) ans+=query(l,r,nl,m,now<<1);
        if(m<r) ans+=query(l,r,m+1,nr,now<<1|1);
        return ans;
    }

    inline void updata(int l,int r,int nl,int nr,int now,int x)
    {
        if(l<=nl && nr<=r)
            {
                lz[now]+=x;
                b[now]+=x*(nr-nl+1);
                return;
            }
        if(lz[now]) pushdown(now,nr-nl+1);
        int mid=((nr-nl)>>1)+nl;
        if(l<=mid) updata(l,r,nl,mid,now<<1,x);
        if(mid<r) updata(l,r,mid+1,nr,now<<1|1,x);
        b[now]=(b[now<<1]+b[now<<1|1]) ;
        return;
    }
}tre;
//线段树撒花!!??ヽ(°▽°)ノ?

int n;

inline int quer(int u,int v)
{
    int ans=0;
    while(top[u]!=top[v])
        {
            if(dep[top[u]]<dep[top[v]]) swap(u,v);
           ans+=tre.query(id[top[u]],id[u],1,n,1);
           ans%=mod;
            u=fa[top[u]];
        }
    if(dep[u]>dep[v]) swap(u,v);
    ans+=tre.query(id[u],id[v],1,n,1);
    return ans ;
}

inline void add(int u,int v,int k)
{
    k%=mod;
    while(top[u]!=top[v])
        {
            if(dep[top[u]]<dep[top[v]]) swap(u,v);
            tre.updata(id[top[u]],id[u],1,n,1,k);
            u=fa[top[u]];
        }
    if(dep[u]>dep[v]) swap(u,v);
    tre.updata(id[u],id[v],1,n,1,k);
    return;
}

int m,r;

int main()
{
    cin>>n>>m>>r>>mod;
    for(register int i=1;i<=n;++i) 
        cin>>a[i];
    for(register int i=1;i<n;++i)
        {
            int sz,zc;
            cin>>sz>>zc;
            v[sz].push_back(zc);
            v[zc].push_back(sz);
        }

    fa[r]=0;

    dfs1(r,1);
    dfs2(r,r);
    

    tre.build(1,n,1);

    while(m--)
    {
        int op;
        int x,y,z;
        cin>>op;
        if(op==1)
        {cin>>x>>y>>z;add(x,y,z);}
        if(op==2)
        {cin>>x>>y;cout<<quer(x,y)<<endl;}
        if(op==3)
        {cin>>x>>y;tre.updata(id[x],id[x]+sz[x]-1,1,n,1,y);}
        if(op==4)
        {cin>>x;cout<<tre.query(id[x],id[x]+sz[x]-1,1,n,1)<<endl;}
        //  cout<<"_________________________________"<<endl;
        //  int i=5; cout<<id[i]<<' '<<top[id[i]]<<' '<<quer(i,i)<<' '<<tre.query(id[i],id[i]+sz[i]-1,1,n,1)<<endl;
        //  cout<<endl<<"_________________________________"<<endl;
    }
    return 0;
}
2022/7/20 20:50
加载中...