2016暑期集训4-G
POJ 3321 Apple Tree
线段树 dfs序
传送门:HustOJ
传送门:POJ
题意
一棵树,每一个节点(子叶节点与非子叶节点)有一个苹果。两种操作:C操作,针对某个节点,如果这个节点有苹果,就把这个苹果吃了,没有苹果就长出来一个苹果。Q操作,针对区间,查询区间苹果数。
思路
线段树维护苹果 ,注意建图时用前向星,因为这题卡vector。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <iomanip>
#include <string>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN=100007;
const int MA_XN=207;
const int oo=2000000007;
const long long int loo=2000000000000000007ll;
typedef long long int ll;
typedef struct{
int data;
int lazy;
} Tree;
Tree sum[MAXN<<2];
typedef struct{
int in,out;
} Dfs;
Dfs dffs[MAXN];
bool visit[MAXN];
int cnt=1;
typedef struct{
int to,next;
} Graph;
Graph G[MAXN<<1];
int head[MAXN];
void dfs(int n)//dfs序
{
if(!visit[n])
{
dffs[n].in=cnt++;
visit[n]=true;
}
else
{
return;
}
for(int i=head[n];~i;i=G[i].next)
{
dfs(G[i].to);
}
if(visit[n])
{
dffs[n].out=(cnt-1);
}
}
void PushUP(int rt)
{
sum[rt].data=sum[rt<<1].data+sum[rt<<1|1].data;
}
void build(int l,int r,int rt)
{
if(l==r)
{
sum[rt].data=1;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUP(rt);
}
void update(int p,int l,int r,int rt)
{
if(l==r)
{
int temp=sum[rt].data;
sum[rt].data=temp^1;
return;
}
int m=(l+r)>>1;
if(p<=m)
{
update(p,lson);
}
else
{
update(p,rson);
}
PushUP(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return sum[rt].data;
}
int m=(l+r)>>1;
int res=0;
if(L<=m)
{
res+=query(L,R,lson);
}
if(m<R)
{
res+=query(L,R,rson);
}
return res;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(dffs,0,sizeof(dffs));
memset(G,0,sizeof(G));
memset(head,-1,sizeof(head));
memset(sum,0,sizeof(sum));
memset(visit,0,sizeof(visit));
cnt=1;
int ccc=1;
for(int i=0;i<n-1;i++)
{
int a,b;
scanf("%d%d",&a,&b);
G[ccc].to=b;
G[ccc].next=head[a];
head[a]=ccc++;
G[ccc].to=a;
G[ccc].next=head[b];
head[b]=ccc++;
}
dfs(1);
build(1,n,1);
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
char ss[5];
int k;
scanf("%s%d",ss,&k);
if(ss[0]=='Q')
{
int l=dffs[k].in;
int r=dffs[k].out;
int res=query(l,r,1,n,1);
printf("%d\n",res);
}
else
{
update(dffs[k].in,1,n,1);
}
}
}
return 0;
}