wubaiting2020 @ 2019-09-06 18:32:14
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#define countt(k) (tree[k].r-tree[k].l+1)
#define LL long long
#define _max(x,y) (x>y?x:y)
using namespace std;
const int INF=0x3f3f3f3f,MAXX=100005;
int read()
{
int s=0,bj=0;
char ch=getchar();
while(ch<'0'||ch>'9')bj|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return bj?-s:s;
}
void printnum(int x)
{
if(x>9)printnum(x/10);
putchar(x%10^48);
}
void print(int x,char ch)
{
if(x<0){putchar('-');x=-x;}
printnum(x);putchar(ch);
}
int n,m;
struct node{int nx,to;}w[MAXX<<1];int ecnt,h[MAXX];
struct Segment_Tree{int l,r,sum,add;}tree[MAXX<<2];
void AddEdge(int x,int y){w[++ecnt].to=y;w[ecnt].nx=h[x];h[x]=ecnt;}
int prt[MAXX],size[MAXX],dep[MAXX],top[MAXX],tid[MAXX],cnt,son[MAXX];
void DFS1(int x,int fa,int depth)
{
prt[x]=fa;size[x]=1;dep[x]=depth;
for(int i=h[x];i;i=w[i].nx)
{
int y=w[i].to;
if(y^fa){DFS1(y,x,depth+1);size[x]+=size[y];if(size[son[x]]<size[y])son[x]=y;}
}
}
void DFS2(int x,int topp)
{
top[x]=topp;tid[x]=++cnt;
if(!son[x])return;
DFS2(son[x],topp);
for(int i=h[x];i;i=w[i].nx)
{
int y=w[i].to;
if(y^prt[x]&&y^son[x])DFS2(y,y);
}
}
void pushup(int k){tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;}
void pushdown(int k)
{
if(tree[k].add)
{
tree[k<<1].add+=tree[k].add;tree[k<<1|1].add+=tree[k].add;
tree[k<<1].sum+=countt(k<<1)*tree[k].add;tree[k<<1|1].sum+=countt(k<<1|1)*tree[k].add;
tree[k].add=0;
}
}
void Build(int k,int l,int r)
{
tree[k].l=l;tree[k].r=r;
if(l==r)return;
int mid=(l+r)>>1;
Build(k<<1,l,mid);Build(k<<1|1,mid+1,r);
}
int ans=0;
void Add(int k,int l,int r)
{
if(l>tree[k].r||r<tree[k].l)return;
if(l<=tree[k].l&&r>=tree[k].r){tree[k].sum+=countt(k);tree[k].add++;return;}
pushdown(k);
Add(k<<1,l,r);Add(k<<1|1,l,r);
pushup(k);
}
int Ask(int k,int x)
{
if(tree[k].l==tree[k].r)return tree[k].sum;
// if(x>tree[k].r||x<tree[k].l)return 0;
int mid=(tree[k].l+tree[k].r)>>1;
pushdown(k);
if(x<=mid)return Ask(k<<1,x);
else return Ask(k<<1|1,x);
}
void Add_Edge(int x,int y)
{
while(top[x]^top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
// cout<<"ADD"<<tid[top[x]]<<" "<<tid[x]<<endl;
Add(1,tid[top[x]],tid[x]);
x=prt[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
// cout<<"ADD"<<tid[x]+1<<" "<<tid[y]<<endl;
Add(1,tid[x]+1,tid[y]);
}
int main()
{
n=read();m=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
AddEdge(x,y);AddEdge(y,x);
}
DFS1(1,0,1);
DFS2(1,1);
Build(1,1,n);
for(int i=1;i<=m;i++)
{
char ch[2];int x,y;
scanf("%s",ch);
x=read();y=read();
if(ch[0]=='P')Add_Edge(x,y);
else print(Ask(1,(dep[x]>dep[y])?x:y),'\n');
}
// for(int i=1;i<=4*n;i++)cout<<tree[i].sum<<" ";
return 0;
}
by ZhuMingYang @ 2019-09-06 18:52:15
@Soledad 有任何区别吗
by wubaiting2020 @ 2019-09-06 18:53:12
有的 @ZhuMingYang
by Soledad_S @ 2019-09-06 18:53:48
@ZhuMingYang AC既是证明
by ZhuMingYang @ 2019-09-06 18:54:58
@Soledad 我怎么没看出来哪里变了
by MC方块人 @ 2019-09-06 18:55:46
刚学OI……
by wubaiting2020 @ 2019-09-06 18:56:44
@ZhuMingYang 树剖线段树里面是dfs序……
by Soledad_S @ 2019-09-06 18:57:31
@ZhuMingYang 我只是把他的代码粘下来了,实际上应该是
else print(Ask(1,tid[(dep[x]>dep[y])?x:y]),'\n');
by ZhuMingYang @ 2019-09-06 18:58:17
哦哦。。。