社区讨论

样例没过,玄关求调

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

讨论操作

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

当前回复
6 条
当前快照
1 份
快照标识符
@m2671q5w
此快照首次捕获于
2024/10/12 21:30
去年
此快照最后确认于
2025/11/04 17:21
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define rep(x,a,b) for(int x=(a);x<=(b);++x)
#define rop(x,a,b) for(int x=(a);x<(b);++x)
#define per(x,a,b) for(int x=(a);x>=(b);--x)
#define pb push_back
using namespace std;

const int N = 1e5 + 10;

int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}
ll llread(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}

int n, q, rt, md;
int v[N], f[N], dep[N], sz[N], dfn[N], dn, hs[N], top[N], id[N], pl[N];
vector<int> e[N];
//==========================Ïß¶ÎÊ÷========================
struct tree_node{
	int ls, rs;
	int tag, sum;
}t[N<<1];
struct sgm{
	int node = 1;
	inline void pushup( int x ){
		t[x].sum = t[t[x].ls].sum + t[t[x].rs].sum;
		t[x].sum %= md;
	}
	inline void pushdown( int x , int l , int r ){
		int mid = (l + r) >> 1;
		t[t[x].ls].sum += t[x].tag * (mid - l + 1);
		t[t[x].ls].sum %= md;
		t[t[x].rs].sum += t[x].tag * (r - mid);
		t[t[x].rs].sum %= md;
		t[t[x].ls].tag += t[x].tag;
		t[t[x].ls].tag %= md;
		t[t[x].rs].tag += t[x].tag;
		t[t[x].rs].tag %=md;
		t[x].tag = 0;
	}
	inline void build( int x , int l , int r ){
		if( l == r )return t[x].sum = v[l], void();
		int mid = (l + r) >> 1;
		t[x].ls = ++node;
		build(t[x].ls,l,mid);
		t[x].rs = ++node;
		build(t[x].rs,mid+1,r);
		pushup(x);
	}
	inline void update( int x , int l , int r , int lc , int rc , int k ){
		if( lc <= l && r <= rc ){
			t[x].sum += k * (r - l + 1);
			t[x].sum %= md;
			t[x].tag += k;
			t[x].tag %= md;
			return ;
		}
		int mid = (l + r) >> 1;
		pushdown(x,l,r);
		if( lc <= mid )update(t[x].ls,l,mid,lc,rc,k);
		if( rc > mid )update(t[x].rs,mid+1,r,lc,rc,k);
		pushup(x);
	}
	inline int query( int x , int l , int r , int lc , int rc ){
		if( lc <= l && r <= rc ){
			return t[x].sum;
		}
		int res = 0;
		int mid = (l + r) >> 1;
		pushdown(x,l,r);
		if( lc <= mid )res += query(t[x].ls,l,mid,lc,rc);
		res %= md;
		if( rc > mid )res += query(t[x].rs,mid+1,r,lc,rc);
		res %= md;
		pushup(x);
		return res;
	}
}sg; 
//=====================Ê÷ÆÊ=================== 
inline void dfs1( int x , int fa , int d ){
	f[x] = fa, dep[x] = d;
	sz[x] = 1;
	for( int v : e[x] ){
		if( v == fa )continue;
		dfs1(v,x,d+1);
		sz[x] += sz[v];
		hs[x] = ( sz[v] > sz[hs[x]] ? v : hs[x]);
	}
	
}
inline void dfs2( int x , int t ){
	top[x] = t;
	dfn[x] = ++dn;
	id[dfn[x]] = x;
	if( !hs[x] )return ;
	dfs2(hs[x],t);
	for( int v : e[x] )if( v != hs[x] && v != f[x] ) dfs2(v,v);
}
inline void update_link( int x , int y , int k ){
	k %= md;
	while( top[x] != top[y] ){
		if( dep[top[x]] < dep[top[y]] )swap(x,y);
		sg.update(1,1,n,dfn[top[x]],dfn[x],k);
		x = f[top[x]];
	}	
	if( dep[x] > dep[y] )swap(x,y);
	sg.update(1,1,n,dfn[x],dfn[y],k);
}
inline int query_link( int x , int y ){
	int res, ans = 0;
	while( top[x] != top[y] ){cout << 1;
		res = 0;
		if( dep[top[x]] < dep[top[y]] )swap(x,y);
		res = sg.query(1,1,n,dfn[top[x]],dfn[x]);
		ans += res;
		ans %= md;
		x = f[top[x]];
	}
	if( dep[x] > dep[y] )swap(x,y);
	ans += sg.query(1,1,n,dfn[x],dfn[y]);
	ans %= md;
	return ans; 
}
inline void update_tree( int x , int k ){
	sg.update(1,1,n,dfn[x],dfn[x]+sz[x]-1,k);
}
inline int query_tree( int x ){
	int res = 0;
	res = sg.query(1,1,n,dfn[x],dfn[x]+sz[x]-1);
	return res;
}
int main(){
	n = read();q = read();rt = read();md = read();
	for( int i = 1 ; i <= n ; ++i )v[i] = read();
	int u, v;
	for( int i = 1 ; i <= n - 1; ++i ){
		u = read();v = read();
		e[u].pb(v);e[v].pb(u);
	}
	dfs1(rt,-1,1);
	dfs2(rt,rt);
	sg.build(1,1,n);
 	int op, x, y, z; 
	while( q-- ){
		op = read();x = read();
		if( op == 1 ){
			y = read();z = read();
			update_link(x,y,z);
		}
		else if( op == 2 ){
			y = read();
			cout << query_link(x,y) << "\n";
		}
		else if( op == 3 ){
			z = read();
			update_tree(x,z);
		}
		else{
			cout << query_tree(x) << "\n";
		}
	} 
	return 0;
}
输出:
8
18

回复

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

正在加载回复...