传送门
题解:大水题,跑一遍DFS序,树状数组/线段树维护区间和即可。终于,我这种万年线段树菜鸡也试着写BIT了,确实常数小了很多(•‾̑⌣‾̑•)✧˖°。
Segment Tree:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define root 1,1,n
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define pushup(rt) sum[rt]=sum[rt<<1]+sum[rt<<1|1]
const int MAXN=1e5+2;
int n,q;
int head[MAXN],edge=0,in[MAXN],out[MAXN],tim=0;
struct EDGE {
int v,nxt;
}e[MAXN<<1];
int sum[MAXN<<2];
inline int read() {
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
inline void adde(int u,int v) {
e[edge].nxt=head[u],e[edge].v=v,head[u]=edge++;
e[edge].nxt=head[v],e[edge].v=u,head[v]=edge++;
}
void dfs(int p,int fa) {
in[p]=++tim;
for (int i=head[p];~i;i=e[i].nxt) {
int v=e[i].v;
if (v^fa) dfs(v,p);
}
out[p]=tim;
}
void build(int rt,int l,int r) {
if (l==r) {sum[rt]=1;return ;}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void modify(int rt,int l,int r,int pos) {
if (l==r) {sum[rt]^=1;return ;}
int mid=(l+r)>>1;
if (pos<=mid) modify(lson,pos);
else modify(rson,pos);
pushup(rt);
}
int query(int rt,int l,int r,int L,int R) {
if (L<=l&&r<=R) return sum[rt];
int mid=(l+r)>>1,ret=0;
if (L<=mid) ret+=query(lson,L,R);
if (mid<R) ret+=query(rson,L,R);
return ret;
}
int main() {
memset(head,-1,sizeof(head));
n=read();
for (register int i=1;i<n;++i) {
int u=read(),v=read();
adde(u,v);
}
dfs(1,0);
build(root);
q=read();
for (register int f=0;f<q;++f) {
char ss;
while (!isalpha(ss=getchar()));
if (ss^'C') {
int pos=read();
printf("%d\n",query(root,in[pos],out[pos]));
}
else {
int pos=read();
modify(root,in[pos]);
}
}
return 0;
}
Binary Index Tree:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e5+2;
int n,q;
int head[MAXN],edge=0,in[MAXN],out[MAXN],tim=0;
bool app[MAXN];
struct EDGE {
int v,nxt;
}e[MAXN<<1];
int sum[MAXN];
inline int read() {
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
inline void adde(int u,int v) {
e[edge].nxt=head[u],e[edge].v=v,head[u]=edge++;
e[edge].nxt=head[v],e[edge].v=u,head[v]=edge++;
}
void dfs(int p,int fa) {
in[p]=++tim;
for (int i=head[p];~i;i=e[i].nxt) {
int v=e[i].v;
if (v^fa) dfs(v,p);
}
out[p]=tim;
}
void modify(int p) {
int v;
if (app[p]) app[p]=0,v=-1;
else app[p]=1,v=1;
for (int i=p;i<=n;i+=(i&-i))
sum[i]+=v;
}
int query(int p) {
int ret=0;
for (int i=p;i;i-=(i&-i))
ret+=sum[i];
return ret;
}
int main() {
memset(head,-1,sizeof(head));
memset(app,false,sizeof(app));
n=read();
for (register int i=1;i<n;++i) {
int u=read(),v=read();
adde(u,v);
modify(i);
}
modify(n);
dfs(1,0);
q=read();
for (register int f=0;f<q;++f) {
char ss;
while (!isalpha(ss=getchar()));
if (ss^'C') {
int pos=read();
printf("%d\n",query(out[pos])-query(in[pos]-1));
}
else {
int pos=read();
modify(in[pos]);
}
}
return 0;
}