社区讨论

悲伤的树剖,怎么都是TLE三个点 不变的蓝色 求看

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@mi6vptf5
此快照首次捕获于
2025/11/20 11:36
4 个月前
此快照最后确认于
2025/11/20 11:36
4 个月前
查看原帖
别人的代码跑500ms,我的跑5000ms,然而并没有什么差别的样子
巨丑无比而且还不停加玄学优化的代码:
(已经调试两天了,悲伤)
CPP
#include<iostream>
#include<vector>
#include<cstdio>
#include<queue>
#include<map>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<set>
#include<cstring>
#define mid ((l+r)>>1)
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
#define Rint register int
#define lf k<<1
#define ri k<<1|1
#define late c_l,c_r
using namespace std;
typedef long long ll;
const ll INF=99999999;
const int MAXN=200010;
long long n,m,r,mod;
int ecnt,head[MAXN],nxt[MAXN],to[MAXN];
int w[MAXN],wt[MAXN];

long long tree[MAXN<<2],lazy[MAXN<<2];
int heavy[MAXN],dfn[MAXN],father[MAXN],DFS_cnt;
int deep[MAXN],Size[MAXN],Top[MAXN];
long long res;

void DFS_1(int now,int fa){
    deep[now]=deep[fa]+1;
    father[now]=fa;
    Size[now]=1;
    for(Rint i=head[now];i;i=nxt[i]){
        int v=to[i];
        if(v==fa) continue;
        DFS_1(v,now);
        Size[now]+=Size[v];
        if(heavy[now]==0||Size[v]>heavy[now]) heavy[now]=v;
    }
}
void DFS_2(int now,int nowTop){
    dfn[now]=++DFS_cnt;
    wt[DFS_cnt]=w[now];
    Top[now]=nowTop;
    if(!heavy[now]) return;
    DFS_2(heavy[now],nowTop);
    for(Rint i=head[now];i;i=nxt[i]){
        int v=to[i];
        if(v==father[now]||v==heavy[now]) continue;
        DFS_2(v,v);
    }
}
void add(int frm,int to_){
    to[++ecnt]=to_;
    nxt[ecnt]=head[frm];
    head[frm]=ecnt;
}

void pushdown(int k,int lenn){
    lazy[k<<1]+=lazy[k];
    lazy[k<<1|1]+=lazy[k];
    tree[k<<1]+=lazy[k]*(lenn-(lenn>>1));
    tree[k<<1|1]+=lazy[k]*(lenn>>1);
    tree[k<<1]%=mod;
    tree[k<<1|1]%=mod;
    lazy[k]=0;
}
void build(int k,int l,int r)
{
    if(l==r){
        tree[k]=wt[l];
        if(tree[k]>mod) tree[k]%=mod;
        return;
    }
    build(lson);
    build(rson);
    tree[k]=(tree[lf]+tree[ri])%mod;
}
void query(int k,int l,int r,int c_l,int c_r){
    if(l>=c_l&&r<=c_r)
    {
        res+=tree[k];
        res%=mod;
        return;
    }
    if(lazy[k])
        pushdown(k,r-l+1);
    if(c_l<=mid) query(lson,late);
    if(c_r>mid) query(rson,late);
}
void addRange(int k,int l,int r,int x,int c_l,int c_r){
    if(l>=c_l&&r<=c_r){
        lazy[k]+=x;
        tree[k]+=x*(r-l+1);
    }
    else{
		if(lazy[k])
			pushdown(k,r-l+1);
		if(c_l<=mid) addRange(lson,x,late);
		if(c_r>mid) addRange(rson,x,late);
		tree[k]=(tree[lf]+tree[ri])%mod;
	}
}

int getRange(int u,int v)
{
    int re=0;
    while(Top[u]!=Top[v]){
        if(deep[Top[u]]<deep[Top[v]]) swap(u,v);
        res=0;
        query(1,1,n,dfn[Top[u]],dfn[u]);
        //cout<<"add:"<<res<<" to:"<<father[Top[u]]<<endl;
        re+=res;
        re%=mod;
        u=father[Top[u]];
    }
    if(deep[u]>deep[v]) swap(u,v);
    res=0;
    query(1,1,n,dfn[u],dfn[v]);
    re+=res;
    return re%mod;
}
void updRange(int u,int v,int x){
    x%=mod;
    while(Top[u]!=Top[v]){
        if(deep[Top[u]]<deep[Top[v]]) swap(u,v);
        addRange(1,1,n,x,dfn[Top[u]],dfn[u]);
        u=father[Top[u]];
    }
    if(deep[u]>deep[v]) swap(u,v);
    addRange(1,1,n,x,dfn[u],dfn[v]);
}
int getSonTree(int l){
    res=0;
    query(1,1,n,dfn[l],dfn[l]+Size[l]-1);
    return res;
}
void updSonTree(int l,int x){
    addRange(1,1,n,x,dfn[l],dfn[l]+Size[l]-1);
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    
    cin>>n>>m>>r>>mod;
    for(Rint i=1;i<=n;i++){
        cin>>w[i];
    }
    for(Rint i=1;i<n;i++){
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    DFS_1(r,0);
    DFS_2(r,r);
    build(1,1,n);
    for(Rint J=1;J<=m;J++){
        int a,b,c,d;
        cin>>a>>b;
        if(a==1){
            cin>>c>>d;
            updRange(b,c,d);
        }
        else if(a==2){
            cin>>c;
            cout<<getRange(b,c)%mod<<endl;
        }
       else  if(a==3){
            cin>>c;
            updSonTree(b,c);
        }
        else{
            cout<<getSonTree(b)%mod<<endl;
        }
    }
    return 0;
}

回复

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

正在加载回复...