社区讨论
树链剖分WA on 6求调
CF343DWater Tree参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mhk7286o
- 此快照首次捕获于
- 2025/11/04 14:34 4 个月前
- 此快照最后确认于
- 2025/11/04 14:34 4 个月前
rt
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100010;
int n,m,w[N],vl[N];
int dfn[N],lastdfn[N];
vector<int> v[N];
namespace segment{
int tree[N<<2],tag[N<<2];
int ls(int xx){
return xx*2;
}
int rs(int xx){
return xx*2+1;
}
void pushup(int now){
tree[now]=tree[ls(now)]+tree[rs(now)];
}
void add_tag(int now,int l,int r,int val){
tree[now]=val*(r-l+1);
tag[now]=val;
}
void pushdown(int now,int l,int r){
if(tag[now]==-1) return;
int mid=(l+r)>>1;
add_tag(ls(now),l,mid,tag[now]);
add_tag(rs(now),mid+1,r,tag[now]);
tag[now]=-1;
}
void build(int now,int l,int r){
tag[now]=-1;
if(l==r){
tree[now]=vl[l];
return;
}
int mid=(l+r)>>1;
build(ls(now),l,mid);
build(rs(now),mid+1,r);
pushup(now);
}
void update(int now,int l,int r,int ll,int rr,int val){
if(l>=ll && r<=rr){
add_tag(now,l,r,val);
return;
}
int mid=(l+r)>>1;
pushdown(now,l,r);
if(ll<=mid) update(ls(now),l,mid,ll,rr,val);
if(rr>mid) update(rs(now),mid+1,r,ll,rr,val);
pushup(now);
}
int query(int now,int l,int r,int ll,int rr){
if(l>=ll && r<=rr){
return tree[now];
}
int mid=(l+r)>>1;
int res=0;
pushdown(now,l,r);
if(ll<=mid) res+=query(ls(now),l,mid,ll,rr);
if(rr>mid) res+=query(rs(now),mid+1,r,ll,rr);
pushup(now);
return res;
}
}
namespace tree_pou{
int cnt,siz[N],son[N],father[N],dep[N],top[N];
void get_son(int x,int fa,int d){
siz[x]=1;
father[x]=fa;
dep[x]=d;
int maxsize=0;
for(int i=0;i<v[x].size();i++){
int to=v[x][i];
if(to==fa) continue;
get_son(to,x,d+1);
siz[x]+=siz[to];
if(siz[to]>maxsize){
maxsize=siz[to],son[x]=to;
}
}
}
void dfs(int x,int fa){
dfn[x]=lastdfn[x]=++cnt;
if(x==1) top[x]=x;
if(son[x]){
top[son[x]]=top[x];
dfs(son[x],x);
lastdfn[x]=max(lastdfn[x],lastdfn[son[x]]);
}
for(int i=0;i<v[x].size();i++){
int to=v[x][i];
if(to==fa || to==son[x]) continue;
top[to]=to;
dfs(to,x);
lastdfn[x]=max(lastdfn[x],lastdfn[to]);
}
}
int get_ans(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=segment::query(1,1,n,dfn[top[x]],dfn[x]);
//cout<<"real: "<<x<<" "<<top[x]<<"\n";
x=father[top[x]];
}
if(dep[y]<dep[x]) swap(x,y);
//cout<<"real: "<<x<<" "<<y<<"\n";
ans+=segment::query(1,1,n,dfn[x],dfn[y]);
return ans;
}
void update(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
segment::update(1,1,n,dfn[top[x]],dfn[x],z);
x=father[top[x]];
}
if(dep[y]<dep[x]) swap(x,y);
segment::update(1,1,n,dfn[x],dfn[y],z);
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
tree_pou::get_son(1,0,1);
tree_pou::dfs(1,0);
for(int i=1;i<=n;i++) vl[dfn[i]]=w[i];//,cout<<"i: "<<i<<" "<<dfn[i]<<" "<<lastdfn[i]<<"\n";
//for(int i=1;i<=n;i++) cout<<"i: "<<i<<" "<<vl[dfn[i]]<<"\n";
segment::build(1,1,n);
cin>>m;
//for(int i=1;i<=n;i++) cout<<"i: "<<i<<" "<<segment::query(1,1,n,dfn[i],dfn[i])<<" "<<dfn[i]<<"\n";
while(m--){
int opt,x,y,z;
cin>>opt;
if(opt==1){
cin>>x;
segment::update(1,1,n,dfn[x],lastdfn[x],1);
}
else if(opt==2){
cin>>x;
tree_pou::update(dfn[1],dfn[x],0);
}
else if(opt==3){
cin>>x;
//cout<<"x: "<<dfn[x]<<"\n";
cout<<segment::query(1,1,n,dfn[x],dfn[x])<<"\n";
}
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...