社区讨论
只AC#10其他都RE了 而且本地能跑
P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mi8kxk68
- 此快照首次捕获于
- 2025/11/21 16:09 4 个月前
- 此快照最后确认于
- 2025/11/21 17:53 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MS=1e6+5;
int n,m,r,mod,a[MS],w[MS],tree[MS*4],tag[MS*4];
int num;
int son[MS]/*重儿子*/,sz[MS]/*子树大小*/,dep[MS]/*深度*/,dfn[MS],fa[MS],top[MS]/*重链顶*/,cnt;
vector<int> e[MS];
void dfs1(int u,int f){
sz[u]=1;
fa[u]=f;
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==f)continue;
dep[v]=dep[u]+1;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int f){
dfn[u]=++cnt;
w[dfn[u]]=a[u];
if(top[f]==0||son[f]!=u)top[u]=u;
else top[u]=top[f];
if(son[u]==0)return;
dfs2(son[u],u);
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==f)continue;
if(v==son[u])continue;
dfs2(v,u);
}
}
void build(int p,int l,int r){
if(l==r){
tree[p]=w[l]%mod;
return;
}
int mid=(l+r)/2;
build(p+p,l,mid);
build(p+p+1,mid+1,r);
tree[p]=(tree[p+p]+tree[p+p+1])%mod;
}
void pushdown(int p,int l,int r){
// printf("%d %d %d %d\n",p,l,r,tag[p]);
if(l!=r){
int mid=(r+l)/2;
tree[p+p]=(tree[p+p]+tag[p]*(mid-l+1))%mod;
tree[p+p+1]=(tree[p+p+1]+tag[p]*(r-mid))%mod;
tag[p+p]=(tag[p+p]+tag[p])%mod;
tag[p+p+1]=(tag[p+p+1]+tag[p])%mod;
}
tag[p]=0;
}
void change(int p,int l,int r,int x,int y,int z){
// if(p>1e6){cout<<"Q";return;}
if(x>y)return;
if(tag[p])pushdown(p,l,r);
if(l==x&&r==y){
tree[p]=(tree[p]+(r-l+1)*z)%mod;
tag[p]=(tag[p]+z)%mod;
return;
}
int mid=(l+r)/2;
if(y<=mid)change(p+p,l,mid,x,y,z);
else if(x>mid)change(p+p+1,mid+1,r,x,y,z);
else{
change(p+p,l,mid,x,mid,z);
change(p+p+1,mid+1,r,mid+1,y,z);
}
tree[p]=(tree[p+p]+tree[p+p+1])%mod;
}
int query(int p,int l,int r,int x,int y){
// if(p>1e6){cout<<"Q";return 0;}
if(x>y)return 0;
if(tag[p])pushdown(p,l,r);
if(l==x&&r==y){
return tree[p];
}
int mid=(l+r)/2;
if(y<=mid)return query(p+p,l,mid,x,y);
else if(x>mid)query(p+p+1,mid+1,r,x,y);
else return (query(p+p,l,mid,x,mid)+query(p+p+1,mid+1,r,mid+1,y))%mod;
}
signed main(){
/* scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&w[i]);
mod=1e9;
build(1,1,n);
for(int i=1;i<=m;i++){
int opt,x,y,z;
scanf("%d%d%d",&opt,&x,&y);
if(opt==1){
scanf("%d",&z);
change(1,1,n,x,y,z);
}else printf("%d\n",query(1,1,n,x,y));
}
*/ scanf("%lld%lld%lld%lld",&n,&m,&r,&mod);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]),a[i]%=mod;
for(int i=1;i<n;i++){
int u,v;
scanf("%lld%lld",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dep[r]=1;
// debug
dfs1(r,0);
// for(int i=1;i<=n;i++)
// cout<<son[i]<<endl;
// debug
dfs2(r,0);
build(1,1,n);
for(int i=1;i<=m;i++){
int opt,x,y,z;
scanf("%lld%lld",&opt,&x);
if(opt==1){
scanf("%lld%lld",&y,&z);
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
change(1,1,n,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dfn[x]<dfn[y])swap(x,y);
change(1,1,n,dfn[y],dfn[x],z);
}
if(opt==2){
scanf("%lld",&y);
int res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res=(res+query(1,1,n,dfn[top[x]],dfn[x]))%mod;
x=fa[top[x]];
}
if(dfn[x]<dfn[y])swap(x,y);
res=(res+query(1,1,n,dfn[y],dfn[x]))%mod;
printf("%lld\n",res);
}
if(opt==3){
scanf("%lld",&z);
change(1,1,n,dfn[x],dfn[x]+sz[x]-1,z);
}
if(opt==4){
printf("%lld\n",query(1,1,n,dfn[x],dfn[x]+sz[x]-1));
}
}
return 0;
}
/*
8 100 1 10000
0 0 0 0 0 0 0 0
1 2 2 3 3 4 2 5 1 6 6 7 6 8
*/
回复
共 1 条回复,欢迎继续交流。
正在加载回复...