题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=1103
思路
树链剖分裸题,据说可以用一种更优美的链表方式?
代码
#include <cstdio>
const int maxn=250000;
namespace segment_tree
{
int val[maxn<<2];
inline int updata(int x)
{
return val[x]=val[x<<1]+val[x<<1|1];
}
int build(int now,int l,int r)
{
if(l==r)
{
val[now]=1;
return 0;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
updata(now);
return 0;
}
int modify(int now,int l,int r,int pos)
{
if(l==r)
{
val[now]=0;
return 0;
}
int mid=(l+r)>>1;
if(pos<=mid)
{
modify(now<<1,l,mid,pos);
}
else
{
modify(now<<1|1,mid+1,r,pos);
}
updata(now);
return 0;
}
int query(int now,int l,int r,int askl,int askr)
{
if((askl<=l)&&(r<=askr))
{
return val[now];
}
int res=0,mid=(l+r)>>1;
if(askl<=mid)
{
res+=query(now<<1,l,mid,askl,askr);
}
if(mid<askr)
{
res+=query(now<<1|1,mid+1,r,askl,askr);
}
return res;
}
};
int n,m,pre[(maxn<<1)+10],now[maxn+10],son[(maxn<<1)+10],tot;
int dfn[maxn+10],cnt,fa[maxn+10],top[maxn+10],w[maxn+10],size[maxn+10];
inline int ins(int a,int b)
{
pre[++tot]=now[a];
now[a]=tot;
son[tot]=b;
return 0;
}
int first_dfs(int u,int father)
{
fa[u]=father;
size[u]=1;
w[u]=-1;
int j=now[u];
while(j)
{
int v=son[j];
if(v!=father)
{
first_dfs(v,u);
size[u]+=size[v];
if((w[u]==-1)||(size[v]>size[w[u]]))
{
w[u]=v;
}
}
j=pre[j];
}
return 0;
}
int second_dfs(int u,int topfather)
{
top[u]=topfather;
dfn[u]=++cnt;
if(w[u]!=-1)
{
second_dfs(w[u],topfather);
}
int j=now[u];
while(j)
{
int v=son[j];
if((v!=fa[u])&&(v!=w[u]))
{
second_dfs(v,v);
}
j=pre[j];
}
return 0;
}
inline int getans(int x)
{
int ans=0;
while(x)
{
ans+=segment_tree::query(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
return ans;
}
int main()
{
scanf("%d",&n);
for(register int i=1; i<n; ++i)
{
int a,b;
scanf("%d%d",&a,&b);
ins(a,b);
ins(b,a);
}
first_dfs(1,0);
second_dfs(1,1);
segment_tree::build(1,1,n);
segment_tree::modify(1,1,n,1);
scanf("%d",&m);
for(register int i=1; i<n+m; ++i)
{
char s[10];
int a,b;
scanf("%s%d",s,&a);
if(s[0]=='W')
{
printf("%d\n",getans(a));
}
else
{
scanf("%d",&b);
if(fa[a]==b)
{
segment_tree::modify(1,1,n,dfn[a]);
}
else
{
segment_tree::modify(1,1,n,dfn[b]);
}
}
}
return 0;
}