• 异象石


    #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
    ",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
    ",ans/2);
        }
    return 0;
    }
  • 相关阅读:
    Java牛角尖问题之static 静态变量和静态代码块的执行顺序
    蓝桥杯 蚂蚁爬楼梯 递归解最短路程问题
    动态规划系列题目学习
    使用Excel快速生成html表格
    C#使用out输出结果
    C#和sql语句中切割函数SUBSTRING的用法和区别
    C# 对DataTable进行操作
    自动生成表创建sql
    .net core获取根目录并转化字符串
    .net core从配置中读取数据并实例对象
  • 原文地址:https://www.cnblogs.com/lmjer/p/9363885.html
Copyright © 2020-2023  润新知