• lca:异象石(set+dfs序)


    题目:https://loj.ac/problem/10132

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,tot=0,N,k=0,head[5000000];
    struct node{
        int to,next,w;
    }e[5000000];
    int depth[9000000],grand[2000000][20],c[5000000],num[5990000];
    long long d[9000000];
    void add(int x,int y,int c)
    {
        e[++tot].next=head[x],e[tot].w=c,e[tot].to=y,head[x]=tot;
    }
    void init()
    {
        N=floor(log(n+0.0)/log(2.0));
        depth[1]=1;
    }
    void dfs(int x)
    {
        num[x]=++k;c[k]=x;
        for(int i=1;i<=N;i++)grand[x][i]=grand[grand[x][i-1]][i-1];
        for(int i=head[x];i;i=e[i].next)
        {
            int v=e[i].to;
            if(v==grand[x][0])continue;
            depth[v]=depth[x]+1;
            grand[v][0]=x;
            d[v]=d[x]+e[i].w;
            dfs(v);
        }
    }
    int lca(int a,int b)
    {
        if(depth[a]>depth[b]) swap(a,b);
        for(int i=N;i>=0;i--){
            if(depth[a]<depth[b]&&depth[grand[b][i]]>=depth[a]) b=grand[b][i];
        }
        if(a==b) return a;
        for(int i=N;i>=0;i--){
            if(grand[a][i]!=grand[b][i]){a=grand[a][i],b=grand[b][i];}
        }
        return grand[a][0];
    }
    set<int> s;
    #define Auto set<int>::iterator
    Auto Left(Auto t)
    {
        if(t==s.begin()) return --s.end();
        return --t;
    }
    Auto Right(Auto t)
    {
        if(t==--s.end()) return s.begin();
        return ++t;
    }
    long long dist(int x,int y)
    {
        return d[x]+d[y]-(d[lca(x,y)]<<1);
    }
    int main()
    {
        char ch[10];
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            add(x,y,z),add(y,x,z);
        }
        init();
        dfs(1);
        scanf("%d",&m);
        Auto l,r;
        long long ans=0;
        for(int i=1;i<=m;i++){
            scanf("%s",ch);
            if(ch[0]=='?') printf("%lld
    ",ans>>1);
            else{
                int x;
                scanf("%d",&x);
                if(ch[0]=='+')
                {
                    if(!s.empty())
                    {
                        r=s.lower_bound(num[x]);
                        if(r==s.end())r=s.begin();
                        l=Left(r);
                        ans+=dist(c[*l],x)+dist(x,c[*r])-dist(c[*l],c[*r]);
                    }
                    s.insert(num[x]);
                }
                else{
                    r=s.find(num[x]);
                    l=Left(r);r=Right(r);
                    ans-=dist(c[*l],x)+dist(x,c[*r])-dist(c[*l],c[*r]);
                    s.erase(num[x]);
                }
            }
        } 
        return 0;
    }

      

  • 相关阅读:
    C# 酒鬼买酒喝,瓶盖和空瓶子可以换新的酒
    C# 图结构操作
    C# 二叉堆
    Unity 单元测试(NUnit,UnityTestTools)
    Unity PlayerPrefs类进行扩展(整个对象进行保存)
    客户端操作判断以服务器时间为准
    C# 使用枚举获取对应的数组值时
    C# 实现简单状态机(参考代码)
    叶脉图案以及藤蔓生长算法在houdini里面的实现 Leaf Venation
    steering behaviors 转向行为 集群模拟 小结
  • 原文地址:https://www.cnblogs.com/719666a/p/9585463.html
Copyright © 2020-2023  润新知