wanghaolin44243787 @ 2024-08-14 00:27:31
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 100005
char x;
ll n,m,a[MAXN], ans[MAXN << 2], tag[MAXN << 2], id[MAXN], y, z, w, tot[MAXN], fa[MAXN], top[MAXN], dep[MAXN], son[MAXN], cnt = 0, v[MAXN], t;
vector<ll>edge[MAXN];
inline void dfs1(ll now, ll f, ll dp) {
fa[now] = f;
dep[now] = dp;
tot[now] = 1;
ll maxson = -1;
for (int i = 0; i < edge[now].size(); i++) {
if (edge[now][i] == f) {
continue;
}
dfs1(edge[now][i], now, dp + 1);
tot[now] += tot[edge[now][i]];
if (maxson < tot[edge[now][i]]) {
maxson = tot[edge[now][i]];
son[now] = edge[now][i];
}
}
return;
}
inline void dfs2(ll now, ll topof) {
id[now] = ++cnt;
v[cnt] = a[now];
top[now] = topof;
if (son[now] == 0)return;
dfs2(son[now], topof);
for (int i = 0; i < edge[now].size(); i++) {
if (edge[now][i] == fa[now] || edge[now][i] == son[now])continue;
dfs2(edge[now][i], edge[now][i]);
}
return;
}
inline void push_down(ll p, ll l, ll r) {
ll mid = l / 2.0 + r / 2.0;
ans[p * 2] += tag[p] * (mid - l + 1);
tag[p * 2] += tag[p];
ans[p * 2 + 1] += tag[p] * (r - mid);
tag[p * 2 + 1] += tag[p];
tag[p] = 0;
}
inline void update(ll dl, ll dr, ll l, ll r, ll p, ll k) {
if (dl <= l && dr >= r) {
ans[p] += k * (r - l + 1);
tag[p] += k;
return ;
}
ll mid = l / 2.0 + r / 2.0;
push_down(p, l, r);
if (dl <= mid)update(dl, dr, l, mid, p * 2, k);
if (dr > mid)update(dl, dr, mid + 1, r, p * 2 + 1, k);
ans[p] = ans[p * 2] + ans[p * 2 + 1];
return;
}
ll query(ll dl, ll dr, ll l, ll r, ll p) {
if (dl <= l && dr >= r)return ans[p];
ll sum = 0;
ll mid = l / 2.0 + r / 2.0;
push_down(p, l, r);
if (dl <= mid) {
sum += query(dl, dr, l, mid, p * 2);
}
if (dr > mid) {
sum += query(dl, dr, mid + 1, r, p * 2 + 1);
}
return sum;
}
inline void tree_update(ll a, ll b, ll c) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
update(id[top[a]], id[a], 1, n, 1, c);
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
update(id[a], id[b], 1, n, 1, c);
return;
}
ll tree_query(ll a, ll b) {
ll qq = 0;
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]])swap(a, b);
qq += query(id[top[a]], id[a], 1, n, 1);
a = fa[top[a]];
}
if (dep[a] > dep[b])swap(a, b);
qq += query(id[a], id[b], 1, n, 1);
return qq;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i < n; i++) {
cin>>y>>z;
edge[z].push_back(y);
edge[y].push_back(z);
}
dfs1(1, 0, 1);
dfs2(1, 1);
for (int i = 1; i <= m; i++) {
cin >> x>>y>>z;
if (x == 'P') {
tree_update(y, z, 1);
}
else if (x == 'Q') {
cout << tree_query(y, z) << "\n";
}
}
return 0;
}