Dream_Stars @ 2024-12-15 19:52:33
为什么 query
的时候要 -1
才能 AC?
我明明已经处理边权问题了啊(见注释)。
# include <bits/stdc++.h>
# define int long long
# define up(i ,x ,y) for (int i = x ; i <= y ; i ++)
using namespace std;
inline int read(){int s = 0 , w = 0;char c = getchar();while(!isdigit(c)){w |= (c == '-');c = getchar();}while(isdigit(c)){s = (s << 1) + (s << 3) + (c ^ 48);c = getchar();}return w ? -s : s;}
inline void write(int x){if(x < 0) putchar('-') , x = -x;if(x > 9) write(x / 10);putchar(x % 10 | 48);}
inline void writesp(int x){write(x) , putchar(' ');}
inline void writeln(int x){write(x) , putchar('\n');}
const int N = 1e5 + 10;
int n ,m, r ,a[N] ,deep[N] ,fa[N] ,sz[N] ,son[N] ,dfn[N] ,tp[N];
int tot ,w[N];
struct Edge {int to ,nxt ;} edge[N << 1] ; int cnt ,head[N];
inline void add (int u ,int v){
edge[++ cnt] = {v ,head[u]} ;
head[u] = cnt;
} inline void dfs1 (int u ,int fath){
deep[u] = deep[fath] + 1, fa[u] = fath;
sz[u] = 1;
int mx = 0;
for (int i = head[u] ; i ; i = edge[i].nxt){
int v = edge[i].to;
if (v == fath) continue;
dfs1 (v ,u);
a[v] = 1;
sz[u] += sz[v];
if (sz[v] > mx){
mx = sz[v];
son[u] = v;
}
}
} inline void dfs2 (int u ,int tops){
tp[u] = tops ,dfn[u] = ++ tot;
w[tot] = a[u];
if (!son[u]) return;//叶节点。
dfs2 (son[u] ,tops);
for (int i = head[u] ; i ; i = edge[i].nxt){
int v = edge[i].to;
if (v == son[u] || v == fa[u]) continue;
dfs2 (v ,v);
}
}
struct sgt {int l ,r ,sum ,lazy;}tr[N << 2];
# define lc u << 1
# define rc u << 1 | 1
inline void pushup (int u){
tr[u].sum = (tr[lc].sum + tr[rc].sum);
} inline void pushdown (int u){
if (tr[u].lazy){
tr[lc].sum += (tr[lc].r - tr[lc].l + 1) * tr[u].lazy ,
tr[rc].sum += (tr[rc].r - tr[rc].l + 1) * tr[u].lazy ;
tr[lc].lazy += tr[u].lazy ,
tr[rc].lazy += tr[u].lazy;
tr[u].lazy = 0;
}
} inline void build (int u ,int l ,int r){
tr[u].l = l ,tr[u].r = r;
if (l == r){
tr[u].sum = w[l];
return ;
}
int mid = ((l + r) >> 1);
build (u << 1 ,l ,mid);
build (u << 1 | 1 ,mid + 1 ,r);
pushup (u);
} inline void update (int u ,int l ,int r ,int ql ,int qr ,int val){
if (l >= ql && r <= qr){
tr[u].sum += (tr[u].r - tr[u].l + 1) * val;
tr[u].lazy += val;
return ;
}
pushdown (u);
int mid = ((l + r) >> 1);
if (ql <= mid) update (u << 1 ,l ,mid ,ql ,qr ,val);
if (mid < qr) update (u << 1 | 1 ,mid + 1, r ,ql ,qr ,val);
pushup (u);
} inline int query (int u ,int l ,int r ,int ql ,int qr){
if (l >= ql && r <= qr) return tr[u].sum;
pushdown (u);
int mid = ((l + r) >> 1) ,res = 0;
if (ql <= mid) res += query (lc ,l ,mid ,ql ,qr);
if (mid < qr) res += query (rc ,mid + 1, r ,ql ,qr);
return res;
} inline void update_edge (int u ,int v ,int val){
while (tp[u] ^ tp[v]){
if (deep[tp[u]] < deep[tp[v]]) swap (u ,v);
update (1 ,1 ,n ,dfn[tp[u]] ,dfn[u] ,val);
u = fa[tp[u]];
}
if (deep[u] > deep[v]) swap (u ,v);
update (1 ,1 ,n ,dfn[u] ,dfn[v] ,val);
update (1 ,1 ,n ,dfn[u] ,dfn[u] ,-val);//1
} inline int query_edge (int u ,int v){
int res = 0;
while (tp[u] ^ tp[v]){
if (deep[tp[u]] < deep[tp[v]]) swap (u ,v);
res += query (1 ,1 ,n ,dfn[tp[u]] ,dfn[u]) ;
u = fa[tp[u]];
}
if (deep[u] > deep[v]) swap (u ,v);
res += query (1 ,1 ,n ,dfn[u] ,dfn[v]);
res -= query (1 ,1 ,n ,dfn[u] ,dfn[u]);//2
return res;
} signed main (){
n = read () ,m = read ();
r = 1;
up (i ,1 ,n - 1){
int u = read () ,v = read ();
add (u ,v) ,add (v ,u);
}
dfs1 (r ,0);
dfs2 (r ,0);
build (1 ,1 ,n);
while (m --){
char op;
cin >> op;
if (op == 'P'){
int x = read () ,y = read () ;
update_edge (x ,y ,1);
} if (op == 'Q'){
int x = read () ,y = read ();
writeln (query_edge (x ,y) - 1);
}
}
return 0;
}