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;
}
然而其上面的点和他的子树是相关的 所以我们要查询一个点 其实是查询一条线
开始想着要多棵树来维护两个不同的值了 应该也是能做的
还有就是转化序列的时候要记得不包括根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;
}
相关文章推荐
- Codeforces Round #200 (Div. 1) D - Water Tree 很经典而且很有趣的树 上dfs问题
- Codeforces Round #200 (Div. 1) D. Water Tree
- CodeForces Round 200 Div2
- Codeforces Round #200 (Div. 2)E
- Codeforces Round 200 Div1 D Water Tree (树上线段树)
- Codeforces Round #200 (Div. 1) Water Tree (dfs序+线段树)
- Codeforces Round #200 (Div. 1)D Water Tree
- Codeforces Round #200 (Div. 1)
- Codeforces Round #200 (Div. 1) D. Water Tree(dfs序+线段树)
- Codeforces Round #200 (Div. 2)
- codeforces round 200 div2解题报告
- Codeforces Round #200 (Div. 2)A. Magnets
- Codeforces Round #200 (Div. 1)A. Rational Resistance 数学
- Codeforces Round #200 (Div. 1)D. Water Tree 【dfs序+线段树】
- Codeforces Round #200 (Div. 2)
- Codeforces Round #200 (Div. 1) (树上的线段树)
- Codeforces Round #200 (Div. 2)344D Alternating Current(栈)
- 【Codeforces Round #200 Div.1 E】【JZOJ 5406】 Tree
- Codeforces Round #200 Div.1 E tree
- Codeforces Round #200 (Div. 2) (ABCDE题解)