题意;
一颗苹果树上有n个树杈,每个树杈都长了一个苹果。C X表示 如果第X个树杈有苹果就摘掉,如果没有就会长出一个。Q X表示 输出X和X的子树杈一共有多少个苹果。
1.线段树
用线段树+vector就会 TLE
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=262144;
int in[maxn],out[maxn]; //对应子树的区间范围
int sum[maxn];
int time,ans,head[maxn];
struct node
{
int to,next;
}p[maxn];
void add(int u,int v)
{
p[ans]=node{v,head[u]};
head[u]=ans++;
}
void dfs(int x,int fa)
{
in[x]=++time;
for(int i=head[x];i!=-1;i=p[i].next)
{
int cnt=p[i].to;
if(cnt==fa)
continue;
dfs(cnt,x);
}
out[x]=time;
}
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void bulid(int l,int r,int rt)
{
if(l==r)
{
sum[rt]=1;
return ;
}
int m=(l+r)>>1;
bulid(l,m,rt<<1);
bulid(m+1,r,rt<<1|1);
pushup(rt);
}
void update(int L,int l,int r,int rt)
{
if(l==r)
{
sum[rt]= (sum[rt]+1)%2;
return ;
}
int m=(l+r)>>1;
if(L<=m)
update(L,l,m,rt<<1);
else
update(L,m+1,r,rt<<1|1);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l && R>=r)
return sum[rt];
int cnt=0;
int m=(l+r)>>1;
if(L<=m)
cnt+=query(L,R,l,m,rt<<1);
if(R>m)
cnt+=query(L,R,m+1,r,rt<<1|1);
return cnt;
}
int main()
{
int n,m;
char s;
scanf("%d",&n);
time=ans=0;
memset(head,-1,sizeof(head));
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
dfs(1,0);
bulid(1,n,1);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf(" %c %d",&s,&x);
if(s=='Q')
printf("%d\n",query(in[x],out[x],1,n,1));
else
update(in[x],1,n,1);
}
return 0;
}
2.树状数组
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=262144;
int in[maxn],out[maxn],c[maxn];
int vis[maxn]; //记录这个点是否有苹果
int time,ans,head[maxn];
int n;
struct node
{
int to,next;
}p[maxn];
void add_add(int u,int v)
{
p[ans]=node{v,head[u]};
head[u]=ans++;
}
void dfs(int x)
{
in[x]=++time;
for(int i=head[x];i!=-1;i=p[i].next)
{
int cnt=p[i].to;
dfs(cnt);
}
out[x]=time;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int v)
{
while(x<=n)
{
c[x] = c[x]+v;
x += lowbit(x);
}
}
int sum(int x)
{
int ans=0;
while(x)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int m;
char s;
scanf("%d",&n);
time=ans=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add_add(x,y);
}
for(int i=1;i<=n;i++)
{
add(i,1);
vis[i]=1;
}
dfs(1);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf(" %c %d",&s,&x);
if(s=='Q')
printf("%d\n",sum(out[x])-sum(in[x]-1));
else
{
if(vis[x])
add(in[x],-1); //更新x所对用的点
else
add(in[x],1);
vis[x] =! vis[x]; //更新该点是否有苹果
}
}
return 0;
}