记录编号 |
563522 |
评测结果 |
AAAAAAAAAA |
题目名称 |
异象石 |
最终得分 |
100 |
用户昵称 |
yrtiop |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.740 s |
提交时间 |
2021-08-19 12:05:50 |
内存使用 |
12.63 MiB |
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100005;
const int INF = 1e9;
typedef long long ll;
ll ans = 0;
int n,m;
int tot;
int point[maxn];
int head[maxn],ver[maxn << 1],nxt[maxn << 1];
ll cost[maxn << 1];
void add(int u,int v,int t) {
ver[++ tot] = v;
nxt[tot] = head[u];
cost[tot] = t;
head[u] = tot;
return ;
}
int rt,sz;
int son[maxn][2],size[maxn],key[maxn],rd[maxn],cnt[maxn];
int pos[maxn];
void pushup(int x) {
size[x] = size[son[x][0]] + size[son[x][1]] + cnt[x];
return ;
}
void rotate(int &x,int d) {
int k = son[x][d ^ 1];
son[x][d ^ 1] = son[k][d];
son[k][d] = x;
pushup(x);
pushup(k);
x = k;
return ;
}
void insert(int &p,int x) {
if(!p) {
p = ++ sz;
size[p] = cnt[p] = 1;
son[p][0] = son[p][1] = 0;
key[p] = x;
rd[p] = rand();
return ;
}
if(key[p] == x) {
++ cnt[p];
++ size[p];
return ;
}
int d = x > key[p];
insert(son[p][d] , x);
if(rd[p] < rd[son[p][d]]) {
rotate(p , d ^ 1);
}
pushup(p);
return ;
}
void remove(int &p,int x) {
if(!p)return ;
if(key[p] != x) {
remove(son[p][x > key[p]] , x);
}
else {
if(!son[p][0]&&!son[p][1]) {
-- cnt[p];
-- size[p];
if(!cnt[p]) {
p = 0;
}
}
else if(son[p][0]&&!son[p][1]) {
rotate(p , 1);
remove(son[p][1] , x);
}
else if(!son[p][0]&&son[p][1]) {
rotate(p , 0);
remove(son[p][0] , x);
}
else {
int d = rd[son[p][0]] > rd[son[p][1]];
rotate(p , d);
remove(son[p][d] , x);
}
}
pushup(p);
return ;
}
int pre(int p,int x) {
if(!p)return -INF;
if(key[p] >= x)return pre(son[p][0] , x);
else return max(key[p] , pre(son[p][1] , x));
}
int suff(int p,int x) {
if(!p)return INF;
if(key[p] <= x)return suff(son[p][1] , x);
else return min(key[p] , suff(son[p][0] , x));
}
int Minimum(int p) {
if(!son[p][0])return key[p];
return Minimum(son[p][0]);
}
int Maximum(int p) {
if(!son[p][1])return key[p];
return Maximum(son[p][1]);
}
int lg[maxn],f[maxn][20];
int d[maxn];
ll dis[maxn];
int dfn[maxn];
int LCA(int u,int v) {
if(d[u] < d[v])swap(u , v);
for(int k = lg[d[u]];~ k;-- k) {
if(d[u] - (1 << k) >= d[v]) {
u = f[u][k];
}
if(u == v)return u;
}
if(u == v)return u;
for(int k = lg[d[u]];~ k;-- k) {
if(f[u][k] != f[v][k]) {
u = f[u][k];
v = f[v][k];
}
}
return f[u][0];
}
ll dist(int u,int v) {
return dis[u] + dis[v] - (dis[LCA(u , v)] << 1);
}
void LCApre(int u,int d) {
for(int k = 1;k <= lg[d];++ k)f[u][k] = f[f[u][k - 1]][k - 1];
return ;
}
void dfs(int u) {
pos[dfn[u] = ++ tot] = u;
for(int i = head[u];i;i = nxt[i]) {
int v = ver[i];
if(dfn[v])continue ;
f[v][0] = u;
d[v] = d[u] + 1;
dis[v] = dis[u] + cost[i];
LCApre(v , d[v]);
dfs(v);
}
return ;
}
int main() {
freopen("visionstone.in","r",stdin);
freopen("visionstone.out","w",stdout);
scanf("%d",&n);
for(int i = 2;i <= n;++ i) {
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
add(u , v , t);
add(v , u , t);
lg[i] = lg[i >> 1] + 1;
}
tot = 0;
dfs(1);
scanf("%d",&m);
for(int i = 1;i <= m;++ i) {
char op;
scanf(" %c",&op);
if(op == '+') {
int u;
scanf("%d",&u);
if(sz) {
int x1 = pre(rt , dfn[u]),x2 = suff(rt , dfn[u]);
if(x1 == -1e9)x1 = Maximum(rt);
if(x2 == 1e9)x2 = Minimum(rt);
int p = pos[x1],s = pos[x2];
ans -= dist(p , s);
ans += dist(p , u) + dist(u , s);
}
insert(rt , dfn[u]);
}
else if(op == '-') {
int u;
scanf("%d",&u);
int x1 = pre(rt , dfn[u]),x2 = suff(rt , dfn[u]);
if(x1 == -1e9)x1 = Maximum(rt);
if(x2 == 1e9)x2 = Minimum(rt);
int p = pos[x1],s = pos[x2];
ans += dist(p , s);
ans -= dist(p , u) + dist(u , s);
remove(rt , dfn[u]);
}
else {
printf("%lld\n",ans >> 1);
}
}
fclose(stdin);
fclose(stdout);
return 0;
}