蒟蒻10pts求调教

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

_AyachiNene @ 2023-05-10 20:43:57

#include<bits/stdc++.h>
#define maxn 114514
#define ls root*2
#define rs root*2+1
using namespace std;
struct node
{
    int nxt,to;
}e[maxn*2];
//----------线段树-------------------
int k;
int n,m,r,p; 

struct node1
{
    int l,r,val,f;
}t[maxn*4];
void bld(int l,int r,int root)
{
    t[root].l=l;
    t[root].r=r;
    if(l==r)
    {
        cin>>t[root].val;
        t[root].val%=p;
        return;
    }
    int mid=(l+r)/2;
    bld(l,mid,root*2);
    bld(mid+1,r,root*2+1);
    t[root].val=(t[ls].val+t[rs].val)%p;
}
void down(int root)
{
    t[ls].f+=t[root].f;
    t[rs].f+=t[root].f;
    t[ls].val=(t[ls].val+(t[ls].r-t[ls].l+1)*t[root].f)%p;
    t[rs].val=(t[rs].val+(t[rs].r-t[rs].l+1)*t[root].f)%p;
    t[root].f=0;
}
void add2(int x,int y,int root,int k)
{
    if(t[root].l>=x&&t[root].r<=y)
    {
        t[root].val+=((t[root].r-t[root].l+1)*k)%p;
        t[root].f+=k;
        return; 
    }
    if(t[root].f)
        down(root);
    int mid=(t[root].l+t[root].r)/2;
    if(x<=mid)
        add2(x,y,root*2,k);
    if(y>mid)
        add2(x,y,root*2+1,k);
    t[root].val=(t[ls].val+t[rs].val)%p;
}
int query(int x,int y,int root)
{
    int ret=0;
    if(t[root].l>=x&&t[root].r<=y)
        return t[root].val;
    if(t[root].f)
        down(root);
    int mid=(t[root].l+t[root].r)/2;
    if(x<=mid)
        ret=(ret+query(x,y,ls))%p;
    if(y>mid)
        ret=(ret+query(x,y,rs))%p;
    return ret;
}
//----------------------------------- 
int head[maxn*2],cnt1;
void add(int u,int v)
{
    e[++cnt1].to=v;
    e[cnt1].nxt=head[u];
    head[u]=cnt1;
}
int top[maxn],dfn[maxn],rk[maxn],son[maxn],size[maxn],f[maxn],dep[maxn],cnt;
void dfs1(int u,int fa)
{
    size[u]=1;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].to;
        if(v!=fa)
        {
            dep[v]=dep[u]+1;
            f[v]=u;
            dfs1(v,u);
            size[u]+=size[v];
            if(size[v]>size[son[u]])
                son[u]=v;
        }
    }
}
void dfs2(int u,int t)
{
    dfn[++cnt]=u;
    top[u]=t;
    if(son[u])
        dfs2(son[u],t);
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].to;
        if(v!=f[u]&&v!=son[u])
            dfs2(v,v);
    }
}
int sum(int x,int y)
{
    int ans=0,fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
            swap(x,y),swap(fx,fy);

        ans+=query(dfn[fx],dfn[x],1);;
        x=f[fx],fx=top[x];
    }
    if(dfn[x]>dfn[y])
        swap(x,y);
    ans+=query(dfn[x],dfn[y],1);
    return ans;
}
void add1(int x,int y,int z)
{
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
            swap(x,y),swap(fx,fy);
        add2(dfn[fx],dfn[x],1,z);
        x=f[fx],fx=top[x];
    }
    if(dfn[x]>dfn[y])
        swap(x,y);
    add2(dfn[x],dfn[y],1,z);
}
int main()
{
    cin>>n>>m>>r>>p;
    bld(1,n,1);
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    dfs1(r,0);
    dfs2(r,r);
    while(m--)
    {
        int op,x,y,z;
        cin>>op;
        if(op==1)
        {
            cin>>x>>y>>z;
            add1(x,y,z);
        }
        else if(op==2)
        {
            cin>>x>>y;
            k=0;
            cout<<sum(x,y)<<endl;
        }
        else if(op==3)
        {
            cin>>x>>z;
            add2(dfn[x],dfn[x]+size[x]-1,1,z);
        }
        else
        {
            cin>>x;
            cout<<query(dfn[x],dfn[x]+size[x]-1,1)<<endl;
        }
    }
//  for(int i=1;i<=10;i++)
//      cout<<t[i].val<<' ';
}

by hegm @ 2023-05-11 15:33:50

@brother_jie 6


by hegm @ 2023-05-11 15:34:22

你还没剖分就读入权值?


by hegm @ 2023-05-11 15:36:46

过了就给个关注吧


by _AyachiNene @ 2023-05-11 22:10:04

@hegm dalao还是10pts啊(悲

#include<bits/stdc++.h>
#define maxn 114514
#define ls root*2
#define rs root*2+1
using namespace std;
struct node
{
    int nxt,to;
}e[maxn*2];
//----------线段树-------------------
int n,m,r,p,a[maxn],w[maxn]; 
struct node1
{
    int l,r,val,f;
}t[maxn*4];
void bld(int l,int r,int root)
{
    t[root].l=l;
    t[root].r=r;
    if(l==r)
    {
        t[root].val=w[l];
        t[root].val%=p;
        return;
    }
    int mid=(l+r)/2;
    bld(l,mid,root*2);
    bld(mid+1,r,root*2+1);
    t[root].val=(t[ls].val+t[rs].val)%p;
}
void down(int root)
{
    t[ls].f+=t[root].f;
    t[rs].f+=t[root].f;
    t[ls].val=(t[ls].val+(t[ls].r-t[ls].l+1)*t[root].f)%p;
    t[rs].val=(t[rs].val+(t[rs].r-t[rs].l+1)*t[root].f)%p;
    t[root].f=0;
}
void add2(int x,int y,int root,int k)
{
    if(t[root].l>=x&&t[root].r<=y)
    {
        t[root].val+=((t[root].r-t[root].l+1)*k)%p;
        t[root].f+=k;
        return;
    }
    if(t[root].f)
        down(root);
    int mid=(t[root].l+t[root].r)/2;
    if(x<=mid)
        add2(x,y,ls,k);
    if(y>mid)
        add2(x,y,rs,k);
    t[root].val=(t[ls].val+t[rs].val)%p;
}
int query(int x,int y,int root)
{
    int ret=0;
    if(t[root].l>=x&&t[root].r<=y)
        return t[root].val;
    if(t[root].f)
        down(root);
    int mid=(t[root].l+t[root].r)/2;
    if(x<=mid)
        ret=(ret+query(x,y,ls))%p;
    if(y>mid)
        ret=(ret+query(x,y,rs))%p;
    return ret;
}
//----------------------------------- 
int head[maxn*2],cnt1;
void add(int u,int v)
{
    e[++cnt1].to=v;
    e[cnt1].nxt=head[u];
    head[u]=cnt1;
}
int top[maxn],dfn[maxn],son[maxn],size[maxn],f[maxn],dep[maxn],cnt;
void dfs1(int u,int fa)
{
    size[u]=1;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].to;
        if(v!=fa)
        {
            dep[v]=dep[u]+1;
            f[v]=u;
            dfs1(v,u);
            size[u]+=size[v];
            if(size[v]>size[son[u]])
                son[u]=v;
        }
    }
}
void dfs2(int u,int t)
{
    dfn[++cnt]=u;
    w[cnt]=a[u];
    top[u]=t;
    if(son[u])
        dfs2(son[u],t);
    for(int i=head[u];i;i=e[i].nxt)
    {
        int v=e[i].to;
        if(v!=f[u]&&v!=son[u])
            dfs2(v,v);
    }
}
int sum(int x,int y)
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        ans=(ans+query(dfn[top[x]],dfn[x],1))%p;
        x=f[top[x]];
    }
    if(dep[x]>dep[y])
        swap(x,y);
    ans=(ans+query(dfn[x],dfn[y],1))%p;
    return ans;
}
void add1(int x,int y,int z)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        add2(dfn[top[x]],dfn[x],1,z);
        x=f[top[x]];
    }
    if(dep[x]>dep[y])
        swap(x,y);
    add2(dfn[x],dfn[y],1,z);
}
int main()
{
    cin>>n>>m>>r>>p;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    dfs1(r,0);
    dfs2(r,r);
    bld(1,n,1);

    while(m--)
    {
        int op,x,y,z;
        cin>>op;
        if(op==1)
        {
            cin>>x>>y>>z;
            add1(x,y,z);
        }
        else if(op==2)
        {
            cin>>x>>y;
            cout<<sum(x,y)<<endl;
        }
        else if(op==3)
        {
            cin>>x>>z;
            add2(dfn[x],dfn[x]+size[x]-1,1,z);
        }
        else
        {
            cin>>x;
            cout<<(query(dfn[x],dfn[x]+size[x]-1,1))%p<<endl;
        }
    }
}

by hegm @ 2023-05-12 06:57:06

@brother_jie 你。。。。。你要不重新学一下树剖?


by hegm @ 2023-05-12 07:00:31

树剖上线段树维护的

$dfn$ 序在 $l\sim r$ 的点,不是编号啊!

by _AyachiNene @ 2023-05-13 12:44:42

@hegm dalao我就是维护的编号啊


by _AyachiNene @ 2023-05-13 14:38:43

破案力,dfs2写错了


by _AyachiNene @ 2023-05-13 14:40:29

@hegm 已关注


|