实在搞不过第二轮的题了、、小火车的题太劲了
所以就在其他队爷虐题的时候默默地修炼算法、
这个题挺裸的、、唯一要注意的就是边权要赋到点上、
所以是这样的:
还要注意一些易错点:
1、跳重链比较的是top的父亲
2、由于点权模拟边权,所以跳的时候 a、b正常,, 重链相同时注意要a-1,b
第一次一遍ac
码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define zuo o<<1,l,mid
#define you o<<1|1,mid+1,r
#define M 250005
int he[M<<2],N,ql[M<<2],ans,top[M],fu[M],x,y,n,m,i,j,sz[M],a,b,op,d[M],dui[M],hson[M];
vector<int>v[M];
char ch;
void up(int o)
{
he[o]=he[o<<1]+he[o<<1|1];
}
void down(int o)
{
int ll=o<<1;
int rr=o<<1|1;
if(ql[o])
{
he[ll]=0;
he[rr]=0;
ql[ll]=1;
ql[rr]=1;
ql[o]=0;
}
}
void jian(int o,int l,int r)
{
if(l==r)
{
he[o]=1;
if(l==1)he[o]=0;
return;
}
int mid=(l+r)>>1;
jian(zuo);
jian(you);
up(o);
}
void gai(int o,int l,int r)
{
if(a<=l&&b>=r)
{
if(op==1)
{ he[o]=0;
ql[o]=1;
}else
{
ans+=he[o];
}
return ;
}
down(o);
int mid=(l+r)>>1;
if(a<=mid)gai(zuo);
if(b>mid)gai(you);
up(o);
}
void dfs1(int now,int fa,int shen)
{
fu[now]=fa;
sz[now]=1;
d[now]=shen;
for(int i=0;i<v[now].size();i++)
{
int nd=v[now][i];
if(nd==fa)continue;
dfs1(nd,now,shen+1);
sz[now]+=sz[nd];
if(sz[hson[now]]<sz[nd])hson[now]=nd;
}
}
void dfs2(int now,int tap)
{
top[now]=tap;
dui[now]=++N;
if(hson[now])dfs2(hson[now],tap);
for(int i=0;i<v[now].size();i++)
{
int nd=v[now][i];if(nd==hson[now]||nd==fu[now])continue;
dfs2(nd,nd);
}
}
void work(int x,int y)
{ans=0;
while(top[x]!=top[y])
{
if(d[top[x]]>d[top[y]])swap(x,y);
if(op==1)
{
a=dui[top[y]];
b=dui[y];
op=1;
gai(1,1,N);
}
if(op==2)
{
a=dui[top[y]];
b=dui[y];
// ans+=
op=2;
gai(1,1,N);
}
y=fu[top[y]];
}
if(d[y]<d[x])swap(y,x);
a=dui[x]+1;
b=dui[y];
gai(1,1,N);
}
int main()
{
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(1,0,1);
dfs2(1,1);
jian(1,1,N);
scanf("%d",&m);
for(int i=1;i<=n+m-1;i++)
{
//cout<<i<<endl;
scanf("%c",&ch);
while(ch=='\n'||ch=='\0') scanf("%c",&ch);
if(ch=='A')
{
scanf("%d%d",&x,&y);
op=1;
work(x,y);
}else
{
scanf("%d",&y);
op=2;
work(1,y);
printf("%d\n",ans);
}
}
}