动态树蒟蒻不会就写LCA了233333,感觉LCA比动态树要好写把
题目链接:戳我~
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int size = 500010;
typedef long long ll;
int n,pos;
char tmp[12];
struct Edge{int to,dist;}edges[size];
int head[size],next[size],tot;
void build(int f,int t,int d)
{
edges[++tot].to = t;
edges[tot].dist = d;
next[tot] = head[f];
head[f] = tot;
}
int f[size][32],maxx[size][32];
int deep[size];
void dfs(int u,int d)
{
deep[u] = d;
for(int i =head[u];i;i = next[i])
{
int v = edges[i].to;
if(!deep[v])
{
f[v][0] = u;
maxx[v][0] = edges[i].dist;
dfs(v,d+1);
}
}
}
int max(int a,int b)
{
if(a > b) return a;
return b;
}
void init()
{
int k = (int)log2(n) + 1;
for(int j = 1;j <= k;j ++)
for(int i = 1;i <= n;i ++)
{
f[i][j] = f[f[i][j-1]][j-1];
maxx[i][j] = max(maxx[f[i][j-1]][j-1],maxx[i][j-1]);
}
}
int findlca(int a,int b)
{
if(deep[a] > deep[b]) swap(a,b);
int k = (int)log2(n)+1;
for(int i = k;i >= 0;i --)
{
if(deep[f[b][i]] < deep[a]) continue;
b = f[b][i];
}
for(int i = k;i >= 0;i --)
{
if(f[a][i] == f[b][i]) continue;
a = f[a][i];
b = f[b][i];
}
if(a != b)
{
a = f[a][0];
}
return a;
}
int findist(int a,int b)
{
int ans = 0;
if(deep[a] > deep[b]) swap(a,b);
int k = (int)log2(n)+1;
for(int i = k;i >= 0;i --)
{
if(deep[f[b][i]] < deep[a]) continue;
ans = max(ans,maxx[b][i]);
b = f[b][i];
}
for(int i = k;i >= 0;i --)
{
if(f[a][i] == f[b][i]) continue;
ans = max(ans,maxx[a][i]);
ans = max(ans,maxx[b][i]);
a = f[a][i];
b = f[b][i];
}
if(a != b)
{
ans = max(ans,maxx[a][0]);
ans = max(ans,maxx[b][0]);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&pos);
for(int i = 1;i < n;i ++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
build(a,b,c);
build(b,a,c);
}
dfs(1,1);
init();
int q,a,b;
ll ans;
scanf("%d",&q);
for(int i = 1;i <= q;i ++)
{
cin>>tmp;
if(tmp[0] == 'Q')
{
scanf("%d%d",&a,&b);
int tm1 = findlca(a,b);
int tm2 = findlca(a,pos);
int tm3 = findlca(b,pos);
ans = findist(b,pos);
// cout<<tm3.ma<<endl;
// cout<<"a="<<a<<" b="<<b<<" pos="<<pos<<endl;
// cout<<"lca(a,b)="<<tm1.lca<<" lca(a,pos)="<<tm2.lca<<" lca(b,pos)="<<tm3.lca<<endl;
if(tm1 == tm2)
{
int tm = findist(a,tm3);
ans += (ll)(tm);
}
else if(tm2 == tm3)
{
int tm = findist(a,tm1);
// cout<<tm1.lca<<" a "<<tm.ma<<endl;
ans += (ll)(tm);
}
else if(tm1 == tm3)
{
int tm = findist(a,tm2);
ans += (ll)(tm);
}
printf("%I64d\n",ans);
}
if(tmp[0] == 'A')
{
scanf("%d%d",&a,&b);
int t = ++n;
build(a,t,b);
build(t,a,b);
deep[t] = deep[a]+1;
f[t][0] = a;
maxx[t][0] = b;
// cout<<maxx[t][0]<<endl;
int k = (int)log2(n)+1;
for(int j = 1;j <= k;j ++)
{
f[t][j] = f[f[t][j-1]][j-1];
maxx[t][j] = max(maxx[f[t][j-1]][j-1],maxx[t][j-1]);
}
}
if(tmp[0] == 'C')
{
scanf("%d",&a);
pos = a;
}
}
return 0;
}