您的位置:首页 > 编程语言 > Go语言

Codeforces Round #200 (Div. 1) D.Water Tree

2014-07-19 17:40 225 查看
树形结构转化为线性结构 然后再进行线段树的成段更新 

然而其上面的点和他的子树是相关的 所以我们要查询一个点 其实是查询一条线

开始想着要多棵树来维护两个不同的值了 应该也是能做的 

还有就是转化序列的时候要记得不包括根1啊  否则RE

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 600111
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)

vector<int> vec[maxn];
int n,a,b,tot,L[maxn],R[maxn],f[maxn];
int c[maxn<<2],sum[maxn<<2];

void dfs(int u,int fa) {
L[u]=++tot; f[u]=fa;
for(int i=0;i<vec[u].size();i++) {
int v=vec[u][i];
if(v!=fa) dfs(v,u);
}
R[u]=tot;
}

void down(int rt,int l,int r){
if(c[rt]!=-1) {
c[ls]=c[rs]=c[rt];
sum[ls]=(mid-l+1)*c[rt];
sum[rs]=(r-mid)*c[rt];
c[rt]=-1;
}
}

void up(int rt) {
sum[rt]=sum[ls]+sum[rs];
}

void ins(int rt,int l,int r,int L,int R,int v){
if(L<=l&&r<=R) c[rt]=v,sum[rt]=(r-l+1)*v;
else {
down(rt,l,r);
if(L<=mid) ins(ls,l,mid,L,R,v);
if(R>mid) ins(rs,mid+1,r,L,R,v);
up(rt);
}
}

int query(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R) return sum[rt];
else {
down(rt,l,r);
int ret=0;
if(L<=mid) ret+=query(ls,l,mid,L,R);
if(R>mid) ret+=query(rs,mid+1,r,L,R);
return ret;
}
}

int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++) {
scanf("%d%d",&a,&b);
vec[a].push_back(b);
vec[b].push_back(a);
}
dfs(1,0);
tot++;
int q;scanf("%d",&q);
while(q--) {
scanf("%d%d",&a,&b);
if(a==1) {
if(query(1,1,tot,L[b],R[b])<(R[b]-L[b]+1)&&f[b])
ins(1,1,tot,L[f[b]],L[f[b]],0);
ins(1,1,tot,L[b],R[b],1);
}
else if(a==2) ins(1,1,tot,L[b],L[b],0);
else {
if(query(1,1,tot,L[b],R[b])<(R[b]-L[b]+1))puts("0");
else puts("1");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm