社区讨论

题目数据是不是更新了

P3384【模板】重链剖分 / 树链剖分参与者 8已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@mi5i5g2p
此快照首次捕获于
2025/11/19 12:28
4 个月前
此快照最后确认于
2025/11/19 12:37
4 个月前
查看原帖
原来能AC的代码现在后三个点TLE,快速读入依然无解。
如果可以,请提供一下后三个点数据吧..
··cpp
CPP
#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
typedef long long ll;
int n,m,r,p;
int head[N],cnt;
struct node{
    int to,ne;
}e[N*2];
int tot;
struct tree{
    int l,r,ls,rs;
    ll sum,tag;
}t[N*2];
int totw;
int a[N],b[N],fa[N],son[N],dep[N],size[N],st[N],ed[N],top[N];
int qread() {
    int ret=0; char ch=getchar();
    while(ch<'0' || ch>'9') ch=getchar();
    while(ch>='0' && ch<='9')   ret=ret*10+ch-'0',ch=getchar();
    return ret;
}
int in(int x,int y) {
    e[++cnt].to=y; e[cnt].ne=head[x]; head[x]=cnt;
}
/*树剖begin*/
void dfs1(int x) {
    size[x]=1;
    for(int i=head[x];i;i=e[i].ne) {
        int y=e[i].to;
        if(fa[x]==y)    continue;
        fa[y]=x; dep[y]=dep[x]+1;
        dfs1(y); size[y]+=size[x];
        if(size[son[x]]<size[y])    son[x]=y;
    }
}
void dfs2(int x) {
    st[x]=ed[x]=++totw;
    int y=son[x];
    if(!y)    return;
    top[y]=top[x]; dfs2(y);
    for(int i=head[x];i;i=e[i].ne) {
        int y=e[i].to;
        if(fa[x]==y || son[x]==y)    continue;
        top[y]=y; dfs2(y);
    }
    ed[x]=totw;
}
/*树剖end*/
void update(int x) {
    t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum;
}
int build(int l,int r) {
    int now=++tot;
    t[now].l=l,t[now].r=r;
    if(l==r) {t[now].sum=b[l]; return now;}
    int mid=l+r>>1;
    t[now].ls=build(l,mid);
    t[now].rs=build(mid+1,r);
    update(now);
    return now;
}
void pushdown(int now) {
    int ls=t[now].ls,rs=t[now].rs;
    if(t[now].tag) {
        if(ls) {
            t[ls].sum+=t[now].tag*ll(t[ls].r-t[ls].l+1);
            t[ls].tag+=t[now].tag;
        }
        if(rs) {
            t[rs].sum+=t[now].tag*ll(t[rs].r-t[rs].l+1);
            t[rs].tag+=t[now].tag;
        }
    }
    t[now].tag=0;
}
void plus_add(int now,int x,int y,ll d) {
    pushdown(now);
    int l=t[now].l,r=t[now].r;
    if(x<=l && y>=r) {
        t[now].tag+=d;
        t[now].sum+=d*ll(t[now].r-t[now].l+1);
        return;
    }
    int mid=l+r>>1;
    if(x<=mid)    plus_add(t[now].ls,x,y,d);
    if(y>mid)    plus_add(t[now].rs,x,y,d);
    update(now);
}
ll get_sum(int now,int x,int y) {
    pushdown(now);
    int l=t[now].l,r=t[now].r;
    if(x<=l && y>=r)    return t[now].sum;
    ll ans=0;
    int mid=l+r>>1;
    if(x<=mid)    ans+=get_sum(t[now].ls,x,y)%p;
    if(y>mid)    ans+=get_sum(t[now].rs,x,y)%p;
    update(now);
    return ans;
}
int main() {
    n=qread(); m=qread(); r=qread(); p=qread();
    for(int i=1;i<=n;i++)    a[i]=qread();
    for(int i=1,x,y;i<n;i++)    x=qread(),y=qread(),in(x,y),in(y,x);
    dfs1(r); dfs2(r);
    for(int i=1;i<=n;i++)    b[st[i]]=a[i]%p;
    int root=build(1,n);
    for(int i=1;i<=m;i++) {
        int x,y,op; ll z;
        op=qread();
        if(op==1) {
            x=qread(),y=qread(),z=qread();
            z%=p;
            while(top[x]!=top[y]) {
                if(dep[top[x]]<dep[top[y]])    swap(x,y);
                plus_add(root,st[top[x]],st[x],z);
                x=fa[top[x]];
            }
            if(st[x]>st[y])    swap(x,y);
            plus_add(root,st[x],st[y],z);
        }
        if(op==2) {
            x=qread(),y=qread();
            ll ans=0;
            while(top[x]!=top[y])
            {
                if(dep[top[x]]<dep[top[y]])    swap(x,y);
                ans+=get_sum(root,st[top[x]],st[x])%p;
                x=fa[top[x]];
            }
            if(st[x]>st[y])    swap(x,y);
            ans+=get_sum(root,st[x],st[y])%p;
            printf("%lld\n",ans%p);
        }
        if(op==3) {
            x=qread(),z=qread();
            z%=p;
            plus_add(root,st[x],ed[x],z);
        }
        if(op==4) {
            x=qread();
            ll ans=0;
            ans+=get_sum(root,st[x],ed[x]);
            printf("%lld\n",ans%p);
        }
    }
    return 0;
}

回复

11 条回复,欢迎继续交流。

正在加载回复...