萌新刚学会打头文件0.001s……树剖求条
查看原帖
萌新刚学会打头文件0.001s……树剖求条
669171
z_yq楼主2024/10/16 14:22


附上评测结果,还有代码,现在是0分

#include<bits/stdc++.h>
#define ll long long
#define lson(x) x<<1
#define rson(x) x<<1|1
using namespace std;
const int N=1e5+9;
ll n,m,root,Mod,cnt,head[N],tot,a[N];
struct edge{ll nxt,to;}e[N<<1];
struct node{ll fa,hson,siz,top,dep,dfn,mdfn;}tr[N];
struct tree{ll lt,rt,sum,tag;}st[N<<2];
inline ll Build_tree(int x,int fa)
{
    tr[x].fa=fa;tr[x].dep=tr[fa].dep;tr[x].siz=1;
    for(int i=head[x];i;i=e[i].nxt)
        if(e[i].to!=fa)
            tr[x].siz+=Build_tree(e[i].to,x),
            tr[x].hson=(tr[tr[x].hson].siz<tr[e[i].to].siz)?e[i].to:tr[x].hson;
    return tr[x].siz;
}
inline ll Get_dfn(int x,int top)
{
    tr[x].top=top;tr[x].dfn=tr[x].mdfn=++tot;
    if(tr[x].hson)
    {
        Get_dfn(tr[x].hson,top);tr[x].mdfn=max(tr[x].mdfn,tr[tr[x].hson].mdfn);
        for(int i=head[x];i;i=e[i].nxt)
            if(e[i].to!=tr[x].fa && e[i].to!=tr[x].hson)
                Get_dfn(e[i].to,e[i].to),tr[x].mdfn=max(tr[x].mdfn,tr[e[i].to].mdfn);
    }
}
inline void add(int x,int y){e[++cnt]={head[x],y};head[x]=cnt;}
inline void Push_up(int id){st[id].sum=(st[lson(id)].sum+st[rson(id)].sum)%Mod;}
inline void Push_down(int id)
{
    if(st[id].tag)
    {
        st[lson(id)].tag+=st[id].tag;
        st[rson(id)].tag+=st[id].tag;
        st[lson(id)].sum+=st[id].tag*(st[lson(id)].rt-st[lson(id)].lt+1)%Mod;
        st[rson(id)].sum+=st[id].tag*(st[rson(id)].rt-st[rson(id)].lt+1)%Mod;
        st[id].tag=0;
    }
}
inline void Build(int lt,int rt,int id)
{
    st[id].lt=lt;st[id].rt=rt;
    if(lt==rt) return st[id].sum=a[lt]%Mod,void();
    int mid=lt+rt>>1;
    Build(lt,mid,lson(id));
    Build(mid+1,rt,rson(id));
    Push_up(id);
}
inline void Change(int lt,int rt,int id,ll x)
{
    if(st[id].lt>=lt && st[id].rt<=rt) return st[id].sum=(st[id].sum+x*(rt-lt+1))%Mod,st[id].tag=(st[id].tag+x)%Mod,void();
    int mid=st[id].lt+st[id].rt>>1;Push_down(id);
    if(lt<=mid) Change(lt,rt,lson(id),x);
    if(rt>mid) Change(lt,rt,rson(id),x);
    Push_up(id);
}
inline ll query(int lt,int rt,int id)
{
    //cout<<lt<<' '<<rt<<' '<<id<<' '<<st[id].sum<<' '<<st[id].lt<<' '<<st[id].rt<<endl;
    if(st[id].lt>=lt && st[id].rt<=rt) return st[id].sum;
    Push_down(id);int mid=st[id].lt+st[id].rt>>1;
    ll res=0;
    if(lt<=mid) res+=query(lt,rt,lson(id));
    if(rt>mid) res+=query(lt,rt,rson(id));
    return res%Mod;
}
inline ll solve4(int x){return query(tr[x].dfn,tr[x].mdfn,1ll)%Mod;}
inline void solve3(int x,int y){Change(tr[x].dfn,tr[x].mdfn,1ll,y);}
inline ll solve2(int x,int y)
{
    int fax=tr[tr[x].top].fa,fay=tr[tr[y].top].fa,ans=0;
    while(fax!=fay)
    {
        if(tr[fax].dep<tr[fay].dep) ans+=query(tr[tr[x].top].dfn,tr[x].dfn,1ll),x=fax;
        else ans+=query(tr[tr[y].top].dfn,tr[y].dfn,1ll),y=fay;
        fax=tr[tr[x].top].fa,fay=tr[tr[y].top].fa;
    }
    if(tr[x].dep<tr[y].dep) ans+=query(tr[y].dfn,tr[x].mdfn,1ll);
    else ans+=query(tr[x].dfn,tr[y].mdfn,1ll);
    return ans;
}
inline void solve1(int x,int y,int z)
{
    int fax=tr[tr[x].top].fa,fay=tr[tr[y].top].fa;
    while(fax!=fay)
    {
        if(tr[fax].dep<tr[fay].dep) Change(tr[tr[x].top].dfn,tr[x].dfn,1ll,z),x=fax;
        else Change(tr[tr[y].top].dfn,tr[y].dfn,1ll,z),y=fay;
        fax=tr[tr[x].top].fa,fay=tr[tr[y].top].fa;
    }
    if(tr[x].dfn<tr[y].dfn) Change(tr[x].dfn,tr[y].dfn,1ll,z);
    else Change(tr[y].dfn,tr[x].dfn,1ll,z);
}
int main()
{
    cin>>n>>m>>root>>Mod;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1,x,y;i<n;i++)
        cin>>x>>y,add(x,y),add(y,x);
    Build_tree(root,0);Get_dfn(root,root);
    Build(1,n,1ll);
    while(m--)
    {
        int type,x,y,z;
        cin>>type>>x;
        if(type==4) cout<<solve4(x)<<endl;
        else if(type==3) cin>>z,solve3(x,z);
        else if(type==2) cin>>y,cout<<solve2(x,y)<<endl;
        else if(type==1) cin>>y>>z,solve1(x,y,z);
    }
    return 0;
}
2024/10/16 14:22
加载中...