您的位置:首页 > 其它

Codeforces Bubble Cup 8 - Finals [Online Mirror] B. Bribes lca

2016-06-24 00:30 495 查看

题目链接:

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\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

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: