CodeForces 191C Fools and Roads 树上的前缀和 LCA
2015-02-07 21:05
351 查看
题目链接:点击打开链接
题意:
给定n个点的树。
下面m个操作,每次给一条路径上的边都染一次。
最后问:每个边被染色的次数。
和去年网赛的一道差不多,就是类似前缀和的做法,
我们在某个点+1然后从叶子节点到根节点求一个前缀和,这样某个点加1就相当于某个点到根的路径都加了1.
所以当我们给[u,v]染色时就 sum[u]++; sum[v]++; sum[LCA(u,v)]-=2;
再把重复的部分减掉即可。
最后求个前缀和。
题意:
给定n个点的树。
下面m个操作,每次给一条路径上的边都染一次。
最后问:每个边被染色的次数。
和去年网赛的一道差不多,就是类似前缀和的做法,
我们在某个点+1然后从叶子节点到根节点求一个前缀和,这样某个点加1就相当于某个点到根的路径都加了1.
所以当我们给[u,v]染色时就 sum[u]++; sum[v]++; sum[LCA(u,v)]-=2;
再把重复的部分减掉即可。
最后求个前缀和。
#include <cstdio> #include <vector> #include <algorithm> #include <iostream> #include <map> #include <set> #include <queue> #include <cstring> #include <cmath> #include <string> using namespace std; typedef pair<int, int> pii; typedef long long ll; const int inf = 1e9; const int mod = 1e9+7; const int N = 5*100001; const int M = 20050; template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x *= -1; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } struct Edge{ int from, to, nex, id; Edge(int f = 0, int t = 0, int n = 0, int i = 0) :from(f), to(t), nex(n), id(i){} }edge[N << 1]; int head , edgenum; void add(int u, int v, int id){ Edge E = { u, v, head[u], id }; edge[edgenum] = E; head[u] = edgenum++; } int fa [20], dep , dis , edge_id ; void bfs(int root){ queue<int> q; fa[root][0] = root; dep[root] = 0; dis[root] = 0; q.push(root); while (!q.empty()){ int u = q.front(); q.pop(); for (int i = 1; i<20; i++)fa[u][i] = fa[fa[u][i - 1]][i - 1]; for (int i = head[u]; ~i; i = edge[i].nex){ int v = edge[i].to; if (v == fa[u][0])continue; edge_id[edge[i].id] = v; dep[v] = dep[u] + 1; dis[v] = dis[u] + 1; fa[v][0] = u; q.push(v); } } } int Lca(int x, int y){ if (dep[x]<dep[y])swap(x, y); for (int i = 0; i<20; i++)if ((dep[x] - dep[y])&(1 << i))x = fa[x][i]; if (x == y)return x; for (int i = 19; i >= 0; i--)if (fa[x][i] != fa[y][i])x = fa[x][i], y = fa[y][i]; return fa[x][0]; } int n, q; void input(){ rd(n); memset(head, -1, sizeof head); edgenum = 0; for (int i = 1, u, v; i < n; i++){ rd(u); rd(v); add(u, v, i); add(v, u, i); } rd(q); } int ans , val ; void put(){ for (int i = 1; i < n; i++)printf("%d ", val[edge_id[i]]); puts(""); } void dfs(int u, int fa){ for (int i = head[u]; ~i; i = edge[i].nex){ int v = edge[i].to; if (v == fa)continue; dfs(v, u); val[u] += val[v]; } } int main() { input(); bfs(1); memset(val, 0, sizeof val); while (q--){ int u, v; rd(u); rd(v); val[u]++; val[v]++; val[ Lca(u, v) ] -= 2; } dfs(1, 1); put(); return 0; } /* 14 1 2 1 3 1 4 2 13 13 14 3 10 10 12 10 11 4 5 5 9 5 8 6 4 6 7 13 1 7 1 14 1 12 1 11 1 9 1 8 5 12 7 11 14 8 9 3 6 10 4 14 3 10 12 13 */
相关文章推荐
- Codeforces-191C: Fools and Roads(LCA)
- 【CodeForces】191C Fools and Roads
- Codeforces 191C Fools and Roads(树链剖分)
- CodeForces 191C Fools and Roads 树链剖分
- CF 191C Fools and Roads lca 或者 树链剖分
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
- Duff in the Army codeforces 588E 树上主席树+lca
- Codeforces 191C Fools and Roads(树链拆分)
- 【uoj#150】【NOIP2015】运输计划 树上前缀和+lca+二分+拓扑排序+特别的卡常数技巧
- CodeForces 题目191C. Fools and Roads(Link Cut Tree,边权加求边权值)
- WOJ 651 离线LCA+链上修改+静态查询(树上前缀和?)
- bzoj4326【2015提高】运输计划(二分答案+lca+树上差分前缀和)
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
- 洛谷 P2597 [ZJOI2012]灾难(拓扑排序+建树+动态LCA+树上前缀和)
- CodeForces 832D Round #425 D Misha, Grisha and Underground :LCA求树上路径长度
- 【CodeForces】E. Xenia and Tree(分块 + LCA)
- Codeforces 536B Tavas and Malekas kmp找所有与前缀匹配的后缀
- [贪心+DFS序列维护树上前缀和]2014 Multi-University Training Contest 5 - 1002 Paths on the tree
- [HNOI2014][BZOJ3572] 世界树|虚树|树上倍增LCA|树型dp|dfs序
- SPOJ Count on a tree(lca+主席树,树上主席树,好题)