• 文章标题


    题解
    比赛的时候以为这是一道动态维护树的中心,看了题解发现自己想错了。公共祖先的题目确实是少
    这次学习了一下set
    发现有非常多使用简便的地方

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <utility>
    using namespace std;
    #define N 111111
    #define iter set<int>::iterator
    int par[N][20];
    int depth[N];
    int dis[N];
    int n,m;
    int p[N];
    int vis[N];
    int cnt;
    int dfn[N];
    vector<pair<int,int>>edge[N];
    
    set<int> ans;
    
    void dfs(int u,int fa){
         dfn[++cnt]=u;
         p[u]=cnt;
         //printf("%d %d
    ",u,fa);
         for(int i=1;i<18;i++){ //寻找他的十八辈祖宗
            par[u][i]=par[par[u][i-1]][i-1];
         }
    
         for(int i=0;i<edge[u].size();i++){
            int v=edge[u][i].first;
            if(fa==v) continue ;
            depth[v] = depth[u] + 1;
            dis[v] = dis[u] + edge[u][i].second;
            par[v][0] = u;
            dfs(v,u);
         }
    }
    
    int lca(int u,int v){
        if(depth[u]>depth[v]) swap(u,v);
        for(int k=0;k<18;k++){
            if((depth[v]-depth[u])>>k&1){
                v = par[v][k];
            }
        }
        if(v==u) return u;
        for(int k=17;k>=0;k--){
            if(par[u][k]!=par[v][k]){
                u=par[u][k];
                v=par[v][k];
            }
        }
        return par[u][0];
    }
    
    int tot;
    
    int add(int u){
        if (ans.empty())
            return 0;
        int x, y;
        //寻找与u相邻的dfs序点
        iter it = ans.lower_bound(p[u]);
        iter itx = it;
        itx--;
    
        if (it == ans.end() || it == ans.begin()) {
            it = ans.begin();
            itx = ans.end();
            itx--;
        }
        y = (*it);
        x = (*itx);
        y = dfn[y];
        x = dfn[x];
        return dis[u] - dis[lca(x, u)] - dis[lca(y, u)] + dis[lca(x, y)];
    }
    
    void init(){
        for(int i=1;i<=n;i++){
            edge[i].clear();
        }
        memset(vis,0,sizeof(vis));
        memset(dfn,0,sizeof(dfn));
        memset(p,0,sizeof(p));
        memset(par,0,sizeof(par));
        memset(dis,0,sizeof(dis));
        memset(depth,0,sizeof(depth));
        cnt=0;
        ans.clear();
    }
    
    int main(){
        int T;
        int cas = 0;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            init();
            int x,y,z;
            for(int i=1;i<n;i++){
                scanf("%d%d%d",&x,&y,&z);
                edge[x].push_back(make_pair(y,z));
                edge[y].push_back(make_pair(x,z));
            }
            /*
            for(int i=1;i<=n;i++){
                    printf("%d :",i);
                    for(int j=0;j<edge[i].size();j++){
                            printf("%d ",edge[i][j].first);
                    }
                    puts("");
            }
            */
            dis[1]=0;
            depth[1]=1;
            dfs(1,-1);
            /*
            for(int i=1;i<=n;i++){
                    printf("%d %d %d
    ",i,dis[i],par[i][0]);
            }
            */
            int sum=0;
            printf("Case #%d:
    ",++cas);
            for(int i=1;i<=m;i++){
                scanf("%d%d",&x,&y);
                int tmp;
    
                if(x==1){
                    if(!vis[y]){
                        vis[y]=1;
                        if (ans.size() == 0) {
                            ans.insert(p[y]);
                        } else {
                            tmp = add(y);
                            ans.insert(p[y]);
                            sum += tmp;
                        }
                    }
                }
                else{
                    if(vis[y]){
                        vis[y] = 0;
                        ans.erase(p[y]);
                        if (!ans.empty()) {
                            sum -= add(y);
                        }
                    }
                }
                printf("%d
    ",sum);
            }
        }
    }
    
  • 相关阅读:
    Spark&Hadoop:scala编写spark任务jar包,运行无法识别main函数,怎么办?
    Linux:krb5
    SqlServer数据库端口默认是1433吗?
    Linux下使用shell实现上传linux下某个目录下所有文件到ftp
    Spark+Hadoop+Hive集群上数据操作记录
    hadoop之 Hadoop2.2.0中HDFS的高可用性实现原理
    虚拟路由冗余协议VRRP
    hadoop 之Hadoop生态系统
    Oracle NoLogging Append 方式减少批量insert的redo_size
    Oracle常用的性能诊断语句
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7111001.html
Copyright © 2020-2023  润新知