网上都是树链剖分,咱不会啊。。。。。。
幸亏用简单线段树也能做,维护一颗树,一边是灌水树,用dfs序搞定,把灌水变成区间操作,开始为0,lazy更新从1开始的灌水时间。
一边是放水树,维护一颗最大树,每次放水更新一个点,更新从1开始的放水时间。
询问时,第一棵树找到询问点的值,第二棵树找到区间里最大值,如果第二棵树区间里最大值
大于第一棵树询问点的值,说明树的子树区间里有一个放水晚于灌水的,则为空。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <string>
#include <vector>
//#include <iostream>
using namespace std;
int dfsnum;
vector<int>mapp[510000];
struct node
{
int ru,chu;
}inf[510000];
struct node0
{
int jinshui,fangshui;
}tree[2110000];
int dfs(int now,int pre)
{
dfsnum++;
inf[now].ru=dfsnum;
for(int i=0;i<mapp[now].size();i++)
{
if(mapp[now][i]==pre)
continue;
dfs(mapp[now][i],now);
}
inf[now].chu=dfsnum;
return 0;
}
int change(int l,int r,int ll,int rr,int now,int num)
{
if(ll<=l&&rr>=r)
{
tree[now].jinshui=num;
return 0;
}
if(tree[now].jinshui!=0)
{
tree[now*2].jinshui=tree[now].jinshui;
tree[now*2+1].jinshui=tree[now].jinshui;
tree[now].jinshui=0;
}
if(rr<=(l+r)/2)
change(l,(l+r)/2,ll,rr,now*2,num);
else if(ll>=(l+r)/2+1)
change((l+r)/2+1,r,ll,rr,now*2+1,num);
else
{
change(l,(l+r)/2,ll,rr,now*2,num);
change((l+r)/2+1,r,ll,rr,now*2+1,num);
}
return 0;
}
int thechange(int l,int r,int point,int now,int num)
{
if(l==r)
{
tree[now].fangshui=num;
return 0;
}
if(point<=(l+r)/2)
thechange(l,(l+r)/2,point,now*2,num);
else
thechange((l+r)/2+1,r,point,now*2+1,num);
tree[now].fangshui=max(tree[now*2].fangshui,tree[now*2+1].fangshui);
return 0;
}
int question(int l,int r,int point,int now)
{
if(l==r)
{
return tree[now].jinshui;
}
if(tree[now].jinshui!=0)
{
tree[now*2].jinshui=tree[now].jinshui;
tree[now*2+1].jinshui=tree[now].jinshui;
tree[now].jinshui=0;
}
if(point<=(l+r)/2)
return question(l,(l+r)/2,point,now*2);
else
return question((l+r)/2+1,r,point,now*2+1);
}
int thequestion(int l,int r,int ll,int rr,int now)
{
if(ll<=l&&rr>=r)
{
return tree[now].fangshui;
}
if(rr<=(l+r)/2)
return thequestion(l,(l+r)/2,ll,rr,now*2);
else if(ll>=(l+r)/2+1)
return thequestion((l+r)/2+1,r,ll,rr,now*2+1);
else return max(thequestion(l,(l+r)/2,ll,rr,now*2),thequestion((l+r)/2+1,r,ll,rr,now*2+1));
}
int main()
{
int i,j,n,k,m,l,p;
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d",&j,&k);
mapp[j].push_back(k);
mapp[k].push_back(j);
}
dfsnum=0;
dfs(1,-1);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&j,&k);
if(j==1)
{
change(1,n,inf[k].ru,inf[k].chu,1,i);
}
else if(j==2)
{
thechange(1,n,inf[k].ru,1,i);
}
else if(j==3)
{
l=question(1,n,inf[k].ru,1);
p=thequestion(1,n,inf[k].ru,inf[k].chu,1);
if(l==0&&p==0)
printf("0\n");
else if(p>l)
printf("0\n");
else
printf("1\n");
}
}
return 0;
}