异象石

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<queue>
using namespace std;
 
typedef long long ll;
 
struct my{
       int v;
       int w;
       int next;
};
 
const int maxn=100000+10;
int t,f[maxn][20],adj[maxn],d[maxn],dfn[maxn],dfsn,a[maxn];
ll dist[maxn],fa;
my bian[maxn*2];
bool vis[maxn];
set<int>s;
typedef set<int>::iterator It;
It it;
queue<int>Q;
 
void myinsert(int u,int v,int w){
     bian[++fa].v=v;
     bian[fa].next=adj[u];
     bian[fa].w=w;
     adj[u]=fa;
}
 
void bfs(){
     Q.push(1);
     d[1]=1;
     while(!Q.empty()){
        int u=Q.front();Q.pop();
        for (int i=adj[u];i;i=bian[i].next){
            int v=bian[i].v;
            if(d[v]) continue;
            d[v]=d[u]+1;
            dist[v]=dist[u]+bian[i].w;
            f[v][0]=u;
            for (int j=1;j<=t;j++){
                f[v][j]=f[f[v][j-1]][j-1];
            }
            Q.push(v);
        }
     }
}
 
int lca(int x,int y){
    if(d[x]>d[y]) swap(x,y);
    for (int i=t;i>=0;i--){
        if(d[f[y][i]]>=d[x]) y=f[y][i];
    }
    if(x==y) return x;
    for (int i=t;i>=0;i--)
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
 
void dfs(int x){
     dfn[x]=++dfsn;
     a[dfsn]=x;
     vis[x]=true;
     for (int i=adj[x];i;i=bian[i].next){
        int v=bian[i].v;
        if(!vis[v]) dfs(v);
    }
}
 
It L(It it){
   if(it==s.begin()) return --s.end();
   return --it;
}
 
It R(It it){
   if(it==--s.end()) return s.begin();
   return ++it;
}
 
ll get(int x,int y){
    return dist[x]+dist[y]-2*(dist[lca(x,y)]);
}
 
int main(){
   // freopen("cou.out","w",stdout);
    int n,q,u,v,w,x,y;
    scanf("%d",&n);
    t=(int)log(n)/log(2)+0.1;
    for (int i=1;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        myinsert(u,v,w);
        myinsert(v,u,w);
    }
    bfs();//for (int i=1;i<=n;i++) printf("%d\n",dist[i]);
    dfs(1);
    char p[10];
    ll ans=0;
    scanf("%d",&q);
    while(q--){
        scanf("%s",p);
        if(p[0]=='+'){
            scanf("%d",&x);
            if(s.size()){
                it=s.lower_bound(dfn[x]);
                if(it==s.end()) it=s.begin();
                y=*L(it);
                ans+=get(x,a[y])+get(x,a[*it])-get(a[*it],a[y]);
            }
            s.insert(dfn[x]);
        }
        else if(p[0]=='-'){
            scanf("%d",&x);
            it=s.find(dfn[x]);
            y=*L(it);
            it=R(it);
            ans-=get(x,a[y])+get(x,a[*it])-get(a[y],a[*it]);
            s.erase(dfn[x]);
        }
        else printf("%lld\n",ans/2);
    }
return 0;
}

猜你喜欢

转载自www.cnblogs.com/lmjer/p/9363885.html