题解:
树上线段树的入门题:感觉没什么可说的,维护区间和我没用线段树,数状数组更方便,但是我还是wa了几发,因为用了
vector
,TLE了,我比赛再也不用vector
了,注意如果建双边的话,数组开两倍,还有时间戳代表区间位置,把dfs序求出来即可
TLE代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define ll long long
const ll maxn=2e5+5;
vector<ll>vec[maxn];
ll n,q,cnt;
ll a[maxn],c[maxn],df[maxn],in[maxn],sizx[maxn];
void dfs(ll u,ll fa)
{
in[u]=++cnt;
df[cnt]=u,sizx[u]=1;;
for(ll i=0;i<vec[u].size();i++)
{
ll v=vec[u][i];
if(v!=fa)
{
dfs(v,u);
sizx[u]+=sizx[v];
}
}
}
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll i,ll w)
{
while(i<=n)
{
c[i]+=w;
i+=lowbit(i);
}
}
ll getsum(ll i)
{
ll res=0;
while(i>0)
{
res+=c[i];
i-=lowbit(i);
}
return res;
}
int main()
{
scanf("%lld",&n);
ll v,u;
for(ll i=1;i<n;i++)
{
scanf("%lld %lld",&u,&v);
a[i]=1;
vec[u].push_back(v);
vec[v].push_back(u);
}
a[n]=1;
dfs(1,0);
for(ll i=1;i<=n;i++)
{
update(i,1);
}
scanf("%lld",&q);
char s[2];
while(q--)
{
scanf("%s",s);
ll pos;
if(s[0]=='Q')
{
scanf("%lld",&pos);
printf("%lld\n",getsum(in[pos]+sizx[pos]-1)-getsum(in[pos]-1));
}
else
{
scanf("%lld",&pos);
if(a[pos])
{
update(in[pos],-1);
}
else
{
update(in[pos],1);
}
a[pos]^=1;
}
}
}
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define ll long long
const ll maxn=2e5+5;
struct node
{
ll to,nex;
} tr[maxn];
ll n,q,cnt,cnx;
ll a[maxn],c[maxn],df[maxn],in[maxn],sizx[maxn];
ll head[maxn];
void add(int u,int v)
{
tr[cnx].to=v;
tr[cnx].nex=head[u];
head[u]=cnx++;
}
void dfs(ll u,ll fa)
{
in[u]=++cnt;
df[cnt]=u,sizx[u]=1;;
for(ll i=head[u]; ~i; i=tr[i].nex)
{
ll v=tr[i].to;
if(v!=fa)
{
dfs(v,u);
sizx[u]+=sizx[v];
}
}
}
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll i,ll w)
{
while(i<=n)
{
c[i]+=w;
i+=lowbit(i);
}
}
ll getsum(ll i)
{
ll res=0;
while(i>0)
{
res+=c[i];
i-=lowbit(i);
}
return res;
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%lld",&n);
ll v,u;
for(ll i=1; i<n; i++)
{
scanf("%lld %lld",&u,&v);
a[i]=1;
add(u,v);
add(v,u);
}
a[n]=1;
dfs(1,0);
for(ll i=1; i<=cnt; i++)
{
update(i,1);
}
scanf("%lld",&q);
char s[2];
while(q--)
{
scanf("%s",s);
ll pos;
if(s[0]=='Q')
{
scanf("%lld",&pos);
printf("%lld\n",getsum(in[pos]+sizx[pos]-1)-getsum(in[pos]-1));
}
else
{
scanf("%lld",&pos);
if(a[pos])
{
update(in[pos],-1);
}
else
{
update(in[pos],1);
}
a[pos]^=1;
}
}
}