标签:
题意比较费劲:输入看起来很麻烦。处理括号冒号的时候是用%1s就可以。还有就是注意它有根节点。。。Q次查询,我是用在线st做的。
/************************************************************************* > File Name: 3.cpp > Author: Howe_Young > Mail: 1013410795@qq.com > Created Time: 2015年10月08日 星期四 19时03分30秒 ************************************************************************/ #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 10000; struct Edge { int to, next; }edge[maxn<<1]; int tot, head[maxn]; int ans[maxn]; int Euler[maxn<<1]; int R[maxn]; int dep[maxn]; int dp[maxn<<1][20]; // RMQ bool in[maxn]; int cnt; void init() { cnt = 0; tot = 0; memset(head, -1, sizeof(head)); memset(ans, 0, sizeof(ans)); memset(in, false, sizeof(in)); } void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void dfs(int u, int depth) { Euler[++cnt] = u; R[u] = cnt; dep[cnt] = depth; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; dfs(v, depth + 1); Euler[++cnt] = u; dep[cnt] = depth; } } void RMQ(int n) { for (int i = 1; i <= n; i++) dp[i][0] = i; int m = (int)(log(n) / log(2)); for (int j = 1; j <= m; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) dp[i][j] = dep[dp[i][j - 1]] < dep[dp[i + (1 << (j - 1))][j - 1]] ? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1]; } } int query(int u, int v) { int l = R[u], r = R[v]; if (l > r) swap(l, r); int k = (int)(log(r - l + 1) / log(2)); int lca = dep[dp[l][k]] < dep[dp[r - (1 << k) + 1][k]] ? dp[l][k] : dp[r - (1 << k) + 1][k]; return Euler[lca]; } int main() { int n; while (~scanf("%d", &n)) { init(); char s1[3], s2[3]; int u, v, m; for (int i = 0; i < n; i++) { scanf("%d %1s %1s %d %1s", &u, s1, s1, &m, s2); for (int j = 0; j < m; j++) { scanf("%d", &v); addedge(u, v); in[v] = true; } } for (int i = 1; i <= n; i++) if (!in[i]) { dfs(i, 1); break; } RMQ(cnt); int Q; scanf("%d", &Q); while (Q--) { scanf("%1s %d %d %1s", s1, &u, &v, s2); ans[query(u, v)]++; } for (int i = 1; i <= n; i++) if (ans[i]) printf("%d:%d\n", i, ans[i]); } return 0; }
POJ 1470 Closest Common Ancestors(LCA&RMQ)
标签:
原文地址:http://www.cnblogs.com/Howe-Young/p/4862255.html