社区讨论
19pts 2,4外TLE,悬两关
P3384【模板】重链剖分 / 树链剖分参与者 5已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @mlgxvw3t
- 此快照首次捕获于
- 2026/02/11 02:33 上周
- 此快照最后确认于
- 2026/02/11 02:33 上周
CPP
#include<bits/stdc++.h>
#define endl '\n'
#define FastIO std::ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
int n,m,r,p;
/*------------------------------------------------------*/
#define ls node<<1
#define rs node<<1|1
#define lb tr[node].l//左边界
#define rb tr[node].r//同理
#define tlt tr[node].lt//懒标记
#define tsum tr[node].sum//和
struct Tree{
int sum,l,r,lt;};
const int N=200005;
Tree tr[4*N];
void push_up(int node){tsum=tr[ls].sum+tr[rs].sum;tsum%=p;}
void push_down(int node){
tr[ls].lt+=tlt;
tr[ls].lt%=p;
tr[rs].lt+=tlt;
tr[rs].lt%=p;
tr[ls].sum+=(tr[ls].r-tr[ls].l+1)*tlt;
tr[ls].sum%=p;
tr[rs].sum+=(tr[rs].r-tr[rs].l+1)*tlt;
tr[rs].sum%=p;
tlt=0;
}
void build(int node,int l,int r){
lb=l,rb=r,tsum=tlt=0;
if(l==r){
tr[node]={0,l,r,0};
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(node);
}
void update(int node,int l,int r,int k){
if(lb>=l&&rb<=r){
tlt+=k;
tsum+=(rb-lb+1)*k;
tsum%=p;
return ;
}
push_down(node);
if(l<=((lb+rb)>>1)) update(ls,l,r,k);
if(r>((lb+rb)>>1)) update(rs,l,r,k);
push_up(node);
}
int query(int node,int l,int r){
if(lb>=l&&rb<=r)
return tsum;
push_down(node);
int res=0;
if(l<=((lb+rb)>>1)) res+=query(ls,l,r);
if(r>((lb+rb)>>1)) res+=query(rs,l,r);
return res;
}
#undef ls
#undef rs
#undef lb
#undef rb
#undef tlt
#undef tsum
/*------------------------------------------------------*/
vector<int>g[N];
int val[N];
int dep[N];
int fa[N];
int siz[N];
int top[N];
int son[N];//重儿子
int id[N];
int rk[N];
int len=0;
void dfs1(int u,int pre){
dep[u]=dep[pre]+1;
fa[u]=pre;
siz[u]=1;
int ma=0;
for(int v:g[u]){
if(v==pre) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>ma){
ma=siz[v];
son[u]=v;
}
}
}
void dfs2(int u,int ttop){
top[u]=ttop;
id[u]=++len;
rk[len]=u;
if(son[u]){
dfs2(son[u],ttop);
for(auto v:g[u]){
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
}
void update1(int x,int y,int k){//链上
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,id[x],id[y],k);
}
int query1(int x,int y){//链上
int res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=query(1,id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
res+=query(1,id[x],id[y]);
return res;
}
void update2(int x,int k){//子树
update(1,id[x],id[x]+siz[x]-1,k);
}
int query2(int x){//子树
return query(1,id[x],id[x]+siz[x]-1);
}
signed main(){
FastIO
cin>>n>>m>>r>>p;
build(1,1,n);
for(int i=1;i<=n;i++){
cin>>val[i];
}
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(r,0);
dfs2(r,1);
for(int i=1;i<=n;i++){
update(1,id[i],id[i],val[i]);
}
while(m--){
int op,x,y,z;
cin>>op>>x;
if(op==1){
cin>>y>>z;
update1(x,y,z%p);
}else if(op==2){
cin>>y;
cout<<query1(x,y)%p<<endl;
}else if(op==3){
cin>>z;
update2(x,z%p);
}else{
cout<<query2(x)%p<<endl;
}
}
}
回复
共 9 条回复,欢迎继续交流。
正在加载回复...