社区讨论
样例没过,玄关求调
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 条回复,欢迎继续交流。
正在加载回复...