zoukankan      html  css  js  c++  java
  • Codeforces Bubble Cup 8

    题目链接:

    http://codeforces.com/contest/575/problem/B

    题解:

     把链u,v拆成u,lca(u,v)和v,lca(u,v)(v,lca(u,v)是倒过来的)。这样就只要考虑自下而上的线性结构了,可以用前缀和的思想来做成段更新。

    代码:

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 1e5 + 10;
    const int DEG = 22;
    const int mod = 1e9 + 7;
    typedef __int64 LL;
    
    struct Edge {
        int v, type;
        Edge() {}
        Edge(int v, int type) :v(v), type(type) {}
    };
    
    int n,q;
    vector<Edge> egs;
    vector<int> G[maxn];
    
    int dep[maxn], anc[maxn][DEG],up[maxn];
    void dfs(int u,int fa) {
        dep[u] = dep[fa] + 1;
        anc[u][0] = fa;
        for (int i = 1; i < DEG; i++) {
            int f = anc[u][i - 1];
            anc[u][i] = anc[f][i - 1];
        }
        for (int i = 0; i < G[u].size(); i++) {
            Edge& e = egs[G[u][i]];
            if (e.v == fa) continue;
            up[e.v] = -e.type;
            dfs(e.v, u);
        }
    }
    
    int cnt[2][maxn];
    int Lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = DEG - 1; i >= 0; i--) {
            if (dep[anc[u][i]]>=dep[v]) {
                u = anc[u][i];
            }
        }
        if (u == v) return u;
        for (int i = DEG - 1; i >= 0; i--) {
            if (anc[u][i] != anc[v][i]) {
                u = anc[u][i];
                v = anc[v][i];
            }
        }
        //printf("u:%d,v:%d
    ", u, v);
        return anc[u][0];
    }
    
    void dfs2(int u, int fa) {
        for (int i = 0; i < G[u].size(); i++) {
            Edge& e = egs[G[u][i]];
            if (e.v == fa) continue;
            dfs2(e.v, u);
            cnt[0][u] += cnt[0][e.v];
            cnt[1][u] += cnt[1][e.v];
        }
    }
    
    void addEdge(int u, int v, int type) {
        egs.push_back(Edge(v, type));
        G[u].push_back(egs.size() - 1);
    }
    
    LL fast_pow(int n) {
        LL ret = 1,x=2;
        while (n) {
            if (n & 1) ret *= x, ret %= mod;
            x *= x, x %= mod;
            n /= 2;
        }
        return ret;
    }
    
    void init() {
        for (int i = 0; i < maxn; i++) G[i].clear();
        egs.clear();
        memset(anc, 0, sizeof(anc));
        memset(dep, 0, sizeof(dep));
        memset(up, 0, sizeof(up));
        memset(cnt, 0, sizeof(cnt));
    }
    
    int main() {
        scanf("%d", &n);
        init();
        for (int i = 0; i < n - 1; i++) {
            int u, v, type;
            scanf("%d%d%d", &u, &v, &type);
            if (type == 0) {
                addEdge(u, v, 0);
                addEdge(v, u, 0);
            }
            else {
                addEdge(u, v, 1);
                addEdge(v, u, -1);
            }
        }
        dfs(1, 0);
        //for (int i = 1; i <= n; i++) {
        //    printf("%d:(%d)",i,dep[i]);
        //    for (int j = 0; j < 20; j++) {
        //        printf("%d ", anc[i][j]);
        //    }
        //    printf("
    ");
        //}
        scanf("%d", &q);
        int s = 1, t;
        while (q--) {
            //scanf("%d%d", &s, &t);
            //printf("(%d,%d):%d
    ", s, t, Lca(s, t));
            scanf("%d", &t);
            int lca = Lca(s, t);
            //printf("(%d,%d):%d
    ", s, t, lca);
            cnt[0][s]++;
            cnt[0][lca]--;
            cnt[1][t]++;
            cnt[1][lca]--;
            s = t;
        }
        dfs2(1, 0);
        LL ans = 0;
        for (int i = 1; i <= n; i++) {
            if (up[i] == -1) {
                ans += fast_pow(cnt[0][i]) - 1;
                ans = (ans + mod) % mod;
            }
            else if (up[i] == 1) {
                ans += fast_pow(cnt[1][i]) - 1;
                ans = (ans + mod) % mod;
            }
        }
        printf("%I64d
    ", ans);
        return 0;
    }
    /*
    7
    1 2 0
    1 3 0
    2 4 0
    2 5 0
    3 6 0
    3 7 0
    
    */
  • 相关阅读:
    INSPIRED启示录 读书笔记
    PHP反射类的理解(代码篇)
    PHP之实现双向链表(代码篇)
    单点登录 SSO 的实现原理 SESSION COOKIE Memcache
    Linux里如何查找文件内容
    PHP获取数组长度的方法 函数参数的比较
    爬虫经验总结
    认证 协议 JWT OAuth Session Cookie
    PHP统计所有字符在字符串中出现的次数
    Nginx 源码安装和调优
  • 原文地址:https://www.cnblogs.com/fenice/p/5612811.html
Copyright © 2011-2022 走看看