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

题目链接:

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

题解:

代码:

#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\n", 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("\n");
    //}
    scanf("%d", &q);
    int s = 1, t;
    while (q--) {
        //scanf("%d%d", &s, &t);
        //printf("(%d,%d):%d\n", s, t, Lca(s, t));
        scanf("%d", &t);
        int lca = Lca(s, t);
        //printf("(%d,%d):%d\n", 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\n", ans);
    return 0;
}
/*
7
1 2 0
1 3 0
2 4 0
2 5 0
3 6 0
3 7 0

*/
时间: 2024-10-14 15:36:18

http://codeforces.com/contest/575/problem/B的相关文章

http://codeforces.com/contest/741/problem/B B. Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses

题意: 给出上限体重W 然后还给出每个人的体重wi 和 魅力值 bi 互为伙伴的对(xi, yi) 可以凑成group 思路: 并查集找出所有的group 暴力背包 对于每一个group 要选出这一组内选一个人时的最优结果, 如果所有人的体重和小于等于W,还得考虑选所有人的情况 #include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include &l

http://codeforces.com/contest/776/problem/G

题意: 讲一个16进制的数字num的每一位拆分下来 也就是sum = $\sigma(2 ^ a_i)$ 每一个a_i 都是不同的 举个栗子: $1014_16$ 就是 $2^1 + 2 ^ 0 + 2 ^ 4$ 求得的sum是个十进制的数字 然后将sum和num都化为二进制进行异或,如果异或后的值小于num那么++ans 现在题目是给出一个区间[l, r] 问这个区间内有多少个满足条件的数,也就是区间内ans的大小 思路: 贪心+数位dp, 定义三个状态 dp[mask1][mask2][le

http://codeforces.com/contest/535/problem/C

C. Tavas and Karafs time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Karafs is some kind of vegetable in shape of an 1?×?h rectangle. Tavaspolis people love Karafs and they use Karafs in al

http://www.codeforces.com/contest/703/problem/D D. Mishka and Interesting sum (莫队的TLE)

/*莫队算法的常数优化 实战演练 虽然是TLE代码*/ #include<bits/stdc++.h> using namespace std; const int maxn = 1000000 + 100; int block; struct query{ int l, r, id; bool operator < (const query &rhs)const{ return (l/block == rhs.l /block) ? r < rhs.r : l/block

http://codeforces.com/contest/349

A. Cinema Line time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The new "Die Hard" movie has just been released! There are n people at the cinema box office standing in a huge line. Ea

[Codeforces 986E] Prince&#39;s Problem

[题目链接] https://codeforces.com/contest/986/problem/E [算法] X到Y的路径积 , 可以转化为X到根的路径积乘Y到根的路径积 , 除以LCA到根的路径积 , 再除以LCA父节点到根的路径积 考虑如何计算根到X路径上每个点与Value的GCD之积 不妨对于每个质数P开一个数组cnt[] , 表示根到当前节点P^i有多少个 , 我们可以在DFS的过程中维护这个数组 将询问离线即可 时间复杂度 : O(V + NlogN + QlogV^2) [代码]

Frets On Fire --- 2019 Codeforces Global Round 2 Problem D

原题:https://codeforces.com/contest/1119/problem/D 题意大概是一个n行1e18列的矩阵,其中每行第一个数为s[i],剩下的数每行依次以1的速度递增.就是说,矩阵元素 a[i][j] = s[i] + j .有q个询问,每个询问有两个参数l,r,求矩阵第l列到第r列(所有行)一共出现了几个不同的数. 这道题首先要先想到,两个参数 [l,r] 其实等价于一个参数 [0,r-l] ,也就是说矩阵第0~r-l行出现的数字的个数其实和第l-r行出现的个数是一样

Codeforces 442B Andrey and Problem(贪心)

题目链接:Codeforces 442B Andrey and Problem 题目大意:Andrey有一个问题,想要朋友们为自己出一道题,现在他有n个朋友,每个朋友想出题目的概率为pi,但是他可以同时向多个人寻求帮助,不过他只能要一道题,也就是如果他向两个人寻求帮助,如果两个人都成功出题,也是不可以的. 解题思路:贪心,从概率最大的人开始考虑,如果询问他使得概率变大,则要询问. #include <cstdio> #include <cstring> #include <a

CodeForces 776D The Door Problem【并查集】

CodeForces 776D The Door Problem[并查集]并查集 设 f 1--m 表示 开的情况 m+1--2*m 表示关的情况 对于每盏灯 如果他 是关的 则 x--y x+m--y+m 表示要同关 或者同开 如果他 是开的 则 x+m--y x--y+m 表示一个关 一个开如果一盏灯 的 x 连向 了 x+m 则表示是矛盾了 那么久是错误的 题意:给你n个门,和m组开关,每扇门都有两个开关控制,每个开关控制x扇门,如果选择了某组开关,则使这组开关里的每个开关控制的所有的门按