ztx__ @ 2020-08-09 11:50:27
调了一上午,心态炸了
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define MAXM 100005
int n,m;
struct edge{
int v,next;
edge(){
v=next=0;
}
};
int p[MAXN],eid;
edge g[MAXM*2];
void insert(int u,int v){
eid++;
g[eid].v=v;
g[eid].next=p[u];
p[u]=eid;
}
int deep[MAXN],dfn[MAXN],top[MAXN],son[MAXN],f[MAXN],size[MAXN],step;
void dfs1(int u,int fa){
deep[u]=deep[fa]+1;
f[u]=fa;
size[u]=1;
int mx=0;
for(int i=p[u];i!=0;i=g[i].next){
int v=g[i].v;
if(v!=fa){
dfs1(v,u);
if(size[v]>size[mx]){
mx=v;
}
}
}
son[u]=mx;
}
void dfs2(int u,int tp){
top[u]=tp;
dfn[u]=++step;
if(son[u]){
dfs2(son[u],tp);
for(int i=p[u];i!=0;i=g[i].next){
int v=g[i].v;
if(v!=f[u]&&v!=son[u]){
dfs2(v,v);
}
}
}
}
int tree[MAXN*4],lazy[MAXN*4];
void push_up(int rt){
tree[rt]=tree[rt*2]+tree[rt*2+1];
}
void push_down(int rt,int l,int r){
if(lazy[rt]){
int mid=(l+r)/2;
lazy[rt*2]+=lazy[rt];
lazy[rt*2+1]+=lazy[rt];
tree[rt*2]+=lazy[rt]*(mid-l+1);
tree[rt*2+1]+=lazy[rt]*(r-mid);
lazy[rt]=0;
}
}
int query(int rt,int l,int r,int L,int R){
if(L>R)swap(L,R);
if(L<=l&&R>=r){
return tree[rt];
}else{
int mid=(l+r)/2,ret=0;
push_down(1,l,r);
if(mid>=L){
ret+=query(rt*2,l,mid,L,R);
}
if(mid<R){
ret+=query(rt*2+1,mid+1,r,L,R);
}
return ret;
}
}
void modify(int rt,int l,int r,int L,int R,int k){
if(L>R)swap(L,R);
if(L<=l&&R>=r){
tree[rt]+=k*(r-l+1);
lazy[rt]+=k;
}else{
int mid=(l+r)/2,ret=0;
push_down(rt,l,r);
if(mid>=L){
modify(rt*2,l,mid,L,R,k);
}
if(mid<R){
modify(rt*2+1,mid+1,r,L,R,k);
}
push_up(rt);
}
}
void plant(int u,int v){
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]){
swap(u,v);
}
modify(1,1,n,dfn[top[u]],dfn[u],1);
u=f[top[u]];
}
if(deep[u]<deep[v]){
swap(u,v);
}
//u更深
modify(1,1,n,dfn[v]+1,dfn[u],1);
}
int query_fj(int u,int v){
int ret=0;
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]){
swap(u,v);
}
ret+=query(1,1,n,dfn[top[u]],dfn[u]);
u=f[top[u]];
}
if(deep[u]<deep[v]){
swap(u,v);
}
//u更深
ret+=query(1,1,n,dfn[v]+1,dfn[u]);
return ret;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n-1;i++){
int u,v;
cin>>u>>v;
insert(u,v);
insert(v,u);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=m;i++){
string str;
int u,v;
cin>>str>>u>>v;
if(str=="P"){
plant(u,v);
}else{
printf("%d\n",query_fj(u,v));
}
}
return 0;
}
by Lates @ 2020-08-09 12:18:56
@ztx666 你dfs1 size[u]要加上每个儿子的size
by Lates @ 2020-08-09 12:21:23
@ztx666 线段树 query 那里pushdown应是
push_down(rt,l,r);
by ztx__ @ 2020-08-09 13:47:28
@Lates 谢谢大佬,已经明白了qwq
这个错误太智障了