树链剖分TLE#8~10求调
查看原帖
树链剖分TLE#8~10求调
444290
wallace_QwQ楼主2024/10/25 20:29
#include <bits/stdc++.h>
#define MAXN 100005
#define mod 10007
#define IINF 0x3f3f3f3f
#define LINF 0x7fffffffffffffff
#define LL long long
#define ULL unsigned long long
using namespace std;
int n,m,root,md;
LL w[MAXN];
vector<int> g[MAXN];
int size1[MAXN],son[MAXN],depth[MAXN],fa[MAXN];
int top[MAXN],id[MAXN],rev[MAXN],cnt; 
LL s[4*MAXN],add[MAXN];
void dfs1(int u){
	size1[u]=1;
	depth[u]=depth[fa[u]]+1;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v!=fa[u]){
            fa[v]=u;
            dfs1(v);
            size1[u]+=size1[v];
            if(size1[son[u]]<size1[v]) son[u]=v;
        }
    }
}
void dfs2(int u,int tp){
    top[u]=tp;
    id[u]=++cnt,rev[cnt]=u;
    if(son[u]) dfs2(son[u],tp);
    for(int i=0,v;i<g[u].size();i++){
        v=g[u][i];
        if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
    }
}

void up(int p){s[p]=(s[p*2]+s[p*2+1])%md;}
void down(int p,int l,int r){
    if(!add[p]) return ;
    int mid=l+r>>1;
    add[p*2]=(add[p*2]+add[p])%md;
    s[p*2]=(s[p*2]+(LL)(mid-l+1)*add[p]%md)%md;
    add[p*2+1]=(add[p*2+1]+add[p])%md;
    s[p*2+1]=(s[p*2+1]+(LL)(r-mid)*add[p]%md)%md;
}
void build(int p,int l,int r){
    add[p]=0;
	if(l==r){
		s[p]=w[rev[l]];
		return ;
	}
	int m=(l+r)>>1;
	build(p*2,l,m); build(p*2+1,m+1,r);
	up(p);
	return ;
}
void update(int p,int l,int r,int x,int y,int v){
	if(y<l||x>r) return ;
	if(l==r){
		s[p]=(s[p]+v*(l-r+1)%md)%md;
        add[p]=(add[p]+v)%md;
		return ;
	}
    down(p,l,r);
	int m=(l+r)>>1;
	update(p*2,l,m,x,y,v); update(p*2+1,m+1,r,x,y,v);
	up(p);
	return ;
}
LL query_sum(int p,int l,int r,int x,int y){
	if(y<l||x>r) return 0;
	if(x<=l&&r<=y){
		return s[p];
    }
    down(p,l,r);
	int m=(l+r)>>1;
    LL ret=0;
    ret=(query_sum(p*2,l,m,x,y)+ret)%md;
    ret=(query_sum(p*2+1,m+1,r,x,y)+ret)%md;
	return ret%md;
}
void ans_add(int u,int v,int qwq){
	while(top[u]!=top[v]){
		if(depth[top[u]]<depth[top[v]]) swap(u,v);
		update(1,1,n,id[top[u]],id[u],qwq);
		u=fa[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	update(1,1,n,id[u],id[v],qwq);
}
LL ans_sum(int u,int v){
	LL ret=0;
	while(top[u]!=top[v]){
		if(depth[top[u]]<depth[top[v]]) swap(u,v);
		ret=(ret+query_sum(1,1,n,id[top[u]],id[u]))%md;
		u=fa[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	ret=(ret+query_sum(1,1,n,id[u],id[v]))%md;
	return ret%md;
}
int main(){
	scanf("%d%d%d%d",&n,&m,&root,&md);
	for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
	for(int i=1,u,v;i<n;i++){
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(root);
	dfs2(root,root);
	build(1,1,n);
	for(int i=1,op,x,y,v;i<=m;i++){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d%d",&x,&y,&v);
            ans_add(x,y,v%md);
        }else if(op==2){
            scanf("%d%d",&x,&y);
            printf("%lld\n",ans_sum(x,y)%md);
        }else if(op==3){
            scanf("%d%d",&x,&v);
            update(1,1,n,id[x],id[x]+size1[x]-1,v%md);
        }else if(op==4){
            scanf("%d",&x);
            printf("%lld\n",query_sum(1,1,n,id[x],id[x]+size1[x]-1)%md);
        }
	}
    return 0;
}
2024/10/25 20:29
加载中...