奇怪问题求问

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

baka24 @ 2024-05-09 17:02:20

此份代码在C++14非O2下AC,但开了O2就会MLE+TLE。

而且本地(windows)测第一组数据没有问题(交上去TLE)

求问为什么,感谢大佬QWQ

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lson (pos<<1)
#define rson (pos<<1|1)
#define pii pair<int,int> 
#define fr first
#define sc second 
#define mk make_pair
#define pb push_back
#define yjbakioi true
#define inx int i=h[u],v=edge[i].v;i;i=edge[i].nx,v=edge[i].v
#define x1 lylakioi
#define y1 gczakioi
inline int read(){int x=0,f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}x=c-'0';c=getchar();while(c<='9'&&c>='0'){x*=10;x+=c-'0';c=getchar();}return x*f;}
const int MAXN=2000010,N=30,base=131,Mod=1000000007,Mod2=999911659,inf=1000000000,B=1000;
struct Edge{int v,nx;}edge[MAXN<<1];int h[MAXN],CNT;
void add_side(int u,int v){edge[++CNT]={v,h[u]};h[u]=CNT;edge[++CNT]={u,h[v]};h[v]=CNT;}
int n,m,r,p,a[MAXN];
int siz[MAXN],top[MAXN],ty,dfn[MAXN],son[MAXN],fa[MAXN],cnt,sd[MAXN],dy[MAXN];
void dfs1(int u,int lst){
    siz[u]=1;fa[u]=lst;
    int mx=0;
    for(inx)if(v!=lst){
        sd[v]=sd[u]+1;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>mx){
            mx=siz[v];
            son[u]=v;
        }
    }
}
void dfs2(int u,int lst){
    dfn[u]=++cnt;top[u]=ty;dy[cnt]=u;
    if(son[u])dfs2(son[u],u);
    for(inx)if(v!=lst&&v!=son[u]){
        ty=v;
        dfs2(v,u);
    }
}
int t[MAXN<<2],lz[MAXN<<2];
int pushup(int pos){
    t[pos]=t[lson]+t[rson];t[pos]%=p;
}
int pushdown(int pos,int l,int r){
    if(lz[pos]){
        int mid=(l+r)>>1;
        t[lson]+=lz[pos]*(mid-l+1);t[lson]%=p;
        t[rson]+=lz[pos]*(r-mid);t[rson]%=p;
        lz[lson]+=lz[pos];lz[lson]%=p;
        lz[rson]+=lz[pos];lz[rson]%=p;
        lz[pos]=0;
    }
}
void build(int pos,int l,int r){
    if(l==r){
        t[pos]=a[dy[l]];t[pos]%=p;
        return;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);build(rson,mid+1,r);
    pushup(pos);
}
void update(int pos,int l,int r,int ql,int qr,int y){
    if(ql<=l&&qr>=r){
        t[pos]+=y*(r-l+1);t[pos]%=p;
        lz[pos]+=y;lz[pos]%=p;
        return;
    }
    pushdown(pos,l,r);
    int mid=(l+r)>>1;
    if(ql<=mid)update(lson,l,mid,ql,qr,y);
    if(qr>mid)update(rson,mid+1,r,ql,qr,y);
    pushup(pos);
}
int query(int pos,int l,int r,int ql,int qr){
    if(ql<=l&&qr>=r){
        return t[pos];
    }
    pushdown(pos,l,r);
    int mid=(l+r)>>1,res=0;
    if(ql<=mid)res=query(lson,l,mid,ql,qr);
    if(qr>mid)res+=query(rson,mid+1,r,ql,qr);
    return res%p;
}
void upd(int x,int y,int z){
    while(top[x]!=top[y]){
        if(sd[top[x]]<sd[top[y]])swap(x,y);
        update(1,1,n,dfn[top[x]],dfn[x],z);
        x=fa[top[x]];
    }
    if(dfn[x]>dfn[y])swap(x,y);
    update(1,1,n,dfn[x],dfn[y],z);
}
int qry(int x,int y){
    int res=0;
    while(top[x]!=top[y]){
        if(sd[top[x]]<sd[top[y]])swap(x,y);
        res+=query(1,1,n,dfn[top[x]],dfn[x]);res%=p;
        x=fa[top[x]];
    }
    if(dfn[x]>dfn[y])swap(x,y);
    res+=query(1,1,n,dfn[x],dfn[y]);res%=p;
    return res;
}
void slv(){
    n=read(),m=read(),r=read(),p=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<n;i++){
        int u=read(),v=read();
        add_side(u,v);
    }
    dfs1(r,r);ty=r;dfs2(r,r);
    build(1,1,n);
    while(m--){
        int opt=read(),x,y,z;
        if(opt==1){
            x=read(),y=read(),z=read();
            upd(x,y,z);
        }
        if(opt==2){
            x=read(),y=read();
            printf("%lld\n",qry(x,y)%p);
        }
        if(opt==3){
            x=read(),z=read();
            update(1,1,n,dfn[x],dfn[x]+siz[x]-1,z);
        }
        if(opt==4){
            x=read();
            printf("%lld\n",query(1,1,n,dfn[x],dfn[x]+siz[x]-1)%p);
        }

    }
}
signed main(){
    slv();
    return 0;
}   

by baka24 @ 2024-05-09 17:03:07

顺便一提,把 MAXN 换回 200010 也会MLE。


by sunkuangzheng @ 2024-05-09 17:05:39

@baka24 你有 \mathcal O(1) 个 int 函数没有返回值。


by baka24 @ 2024-05-09 17:08:37

@sunkuangzheng 感激不尽


|