CF343D Water Tree
其实和一般的树剖区别不大,需要改的地方如下
void spread(int p)
{
if(t[p].add!=-1)
{
t[ls(p)].sum=(t[ls(p)].r-t[ls(p)].l+1)*t[p].add;
t[rs(p)].sum=(t[rs(p)].r-t[rs(p)].l+1)*t[p].add;
t[ls(p)].add=t[rs(p)].add=t[p].add;
t[p].add=-1;
}
}
void change(int p,int l,int r,int d)
{
if(l<=t[p].l&&t[p].r<=r)
{
t[p].add=d;
t[p].sum=d*(t[p].r-t[p].l+1);
return;
}
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
//#define double long long
#define re register int
//#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define mk make_pair
#define P pair < int , int >
using namespace std;
const int mod= 998244353;
//const int inf=1e18;
const int M=1e8;
const int N=2e6+5;//??????.???? 4e8
struct tree
{
int l,r,sum,add;
}t[N];
int n,m,a[N];
int son[N],fa[N],dep[N],dfn[N],sz[N],top[N],w[N],num;
struct ndoe
{
int ver,next;
}e[N];
int tot,head[N];
void add(int x,int y)
{
e[++tot].ver=y;
e[tot].next=head[x];
head[x]=tot;
}
void addedge(int x,int y)
{
add(x,y);add(y,x);
}
void dfs1(int x,int pre)
{
int maxn=-1;
dep[x]=dep[pre]+1;
fa[x]=pre;
sz[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].ver;
if(y==pre) continue;
dfs1(y,x);
sz[x]+=sz[y];
if(sz[y]>maxn)
{
maxn=sz[y];
son[x]=y;
}
}
}
void dfs2(int x,int pre)
{
dfn[x]=++num;
top[x]=pre;
w[num]=a[x];
if(!son[x]) return;
dfs2(son[x],pre);
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].ver;
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
void bulid(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
t[p].sum=0;t[p].add=-1;
if(l==r) return;
int mid=(l+r)>>1;
bulid(ls(p),l,mid);bulid(rs(p),mid+1,r);
}
void spread(int p)
{
if(t[p].add!=-1)
{
t[ls(p)].sum=(t[ls(p)].r-t[ls(p)].l+1)*t[p].add;
t[rs(p)].sum=(t[rs(p)].r-t[rs(p)].l+1)*t[p].add;
t[ls(p)].add=t[rs(p)].add=t[p].add;
t[p].add=-1;
}
}
void pushup(int p)
{
t[p].sum=t[ls(p)].sum+t[rs(p)].sum;
}
int ask(int p,int l,int r)
{
if(l<=t[p].l&&t[p].r<=r) return t[p].sum;
spread(p);
int mid=(t[p].l+t[p].r)>>1;
int ans=0;
if(l<=mid) ans+=ask(ls(p),l,r);
if(mid<r) ans+=ask(rs(p),l,r);
return ans;
}
void change(int p,int l,int r,int d)
{
if(l<=t[p].l&&t[p].r<=r)
{
t[p].add=d;
t[p].sum=d*(t[p].r-t[p].l+1);
return;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change(ls(p),l,r,d);
if(mid<r) change(rs(p),l,r,d);
pushup(p);
}
void mson(int x,int v)
{
change(1,dfn[x],dfn[x]+sz[x]-1,v);
}
void mchain(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(1,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(1,dfn[x],dfn[y],z);
}
void solve()
{
cin>>n;
for(re i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
}
dfs1(1,1);dfs2(1,1);
bulid(1,1,n);
cin>>m;
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x==1) mson(y,1);
if(x==2) mchain(1,y,0);
if(x==3) printf("%d\n",ask(1,dfn[y],dfn[y]));
}
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
solve();
// puts("");
}
return 0;
}
/*
*/