HDU 5044 - Tree (树链剖分)
2016-10-26 20:53
429 查看
感觉一百年没发题解了。
这两天在吴神的嘲讽下终于去做了一年半前就准备学的树剖(:3」∠)
然后随便发个模板题代码吧,证明我还是活着的。
这两天在吴神的嘲讽下终于去做了一年半前就准备学的树剖(:3」∠)
然后随便发个模板题代码吧,证明我还是活着的。
思路
不能用线段树维护,用扫描线的方式,两个端点加减,然后扫一遍。代码
#include <stack> #include <cstdio> #include <list> #include <cassert> #include <set> #include <iostream> #include <string> #include <sstream> #include <vector> #include <queue> #include <functional> #include <cstring> #include <algorithm> #include <cctype> #include <string> #include <map> #include <cmath> #define LL long long #define ULL unsigned long long #define SZ(x) (int)x.size() #define lowbit(x) ((x) & (-x)) #define MP(a, b) make_pair(a, b) #define MS(p, num) memset(p, num, sizeof(p)) #define PB push_back #define X first #define Y second #define ROP freopen("input.txt", "r", stdin); #define MID(a, b) (a + ((b - a) >> 1)) #define LC rt << 1, l, mid #define RC rt << 1|1, mid + 1, r #define LRT rt << 1 #define RRT rt << 1|1 #define FOR(i, a, b) for (int i=(a); (i) < (b); (i)++) #define FOOR(i, a, b) for (int i = (a); (i)<=(b); (i)++) const double PI = acos(-1.0); const int INF = 0x3f3f3f3f; const double eps = 1e-8; const int MAXN = 1e5 + 10; const int MOD = 1e9 + 7; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; //const int seed = 131; int cases = 0; typedef std::pair<int, int> pii; struct Edge { int v, next; Edge(int _v, int _next) : v(_v), next(_next){} }; int id[MAXN], son[MAXN], sz[MAXN], fa[MAXN], top[MAXN], head[MAXN], from[MAXN], to[MAXN], depth[MAXN]; LL ans[2][MAXN], add[2][MAXN]; int n, cnt; std::vector<Edge> edges; void update(int l, int r, int w, int type) { ans[type][l] += w; ans[type][r + 1] -= w; } void change(int u, int v, int w, int type) { while (top[u] != top[v]) { if (depth[top[u]] < depth[top[v]]) std::swap(u, v); update(id[top[u]], id[u], w, type); u = fa[top[u]]; } if (depth[u] > depth[v]) std::swap(u, v); if (type == 0) update(id[u], id[v], w, type); else if (u != v) update(id[son[u]], id[v], w, type); } void addEdge(int u, int v) { edges.push_back(Edge(v, head[u])); head[u] = edges.size() - 1; } void dfs1(int u, int pre, int dep) { fa[u] = pre; sz[u] = 1; son[u] = 0; depth[u] = dep; for (int i = head[u]; ~i; i = edges[i].next) { int v = edges[i].v; if (v == pre) continue; dfs1(v, u, dep + 1); sz[u] += sz[v]; if (sz[v] > sz[son[u]]) son[u] = v; } } void dfs2(int u, int pre) { id[u] = ++cnt; top[u] = pre; if (son[u]) dfs2(son[u], pre); for (int i = head[u]; ~i; i = edges[i].next) { int v = edges[i].v; if (v != fa[u] && v != son[u]) dfs2(v, v); } } void init() { edges.clear(); printf("Case #%d:\n", ++cases); cnt = 0; MS(ans, 0); MS(head, -1); } void getAns() { for (int i = 1; i <= n; ++i) { ans[0][i] += ans[0][i - 1]; ans[1][i] += ans[1][i - 1]; } } int main() { //ROP; int T; scanf("%d", &T); while (T--) { init(); int m; scanf("%d%d", &n, &m); for (int i = 1; i < n; ++i) { scanf("%d%d", &from[i], &to[i]); addEdge(from[i], to[i]); addEdge(to[i], from[i]); } dfs1(1, 0, 0); dfs2(1, 1); for (int i = 1; i < n; ++i) { if (depth[from[i]] < depth[to[i]]) std::swap(from[i], to[i]); } char cmd[10]; while (m--) { int u, v, w; scanf("%s%d%d%d", cmd, &u, &v, &w); if (cmd[3] == '1') change(u, v, w, 0); else change(u, v, w, 1); } getAns(); for (int i = 1; i <= n; ++i) printf("%I64d%c", ans[0][id[i]], i == n ? '\n' : ' '); for (int i = 1; i < n; ++i) printf("%I64d%c", ans[1][id[from[i]]], i == n - 1 ? '\n' : ' '); if (n == 1) puts(""); } return 0; }
相关文章推荐
- HDU 5044 Tree (树链剖分+数组lazy-tag)
- HDU 5044 Tree (树链剖分+区间更新)
- HDU 5044 Tree 树链剖分
- hdu 5044 Tree (树链剖分+打标记)
- HDU-5044 Tree 树链剖分
- HDU 5044 Tree 树链剖分
- HDU 5044 Tree 树链剖分+区间标记
- HDU 5044 Tree --树链剖分
- HDU 5044 Tree 树链剖分
- hdu 5044 Tree(树链剖分)
- HDU 5044 Tree (树链剖分)
- HDU 5044-tree-树链剖分+树状数组
- HDU 5044 Tree 树链剖分
- 【HDU】5044 Tree 树链剖分
- HDU 5044 - Tree (树链剖分)
- hdu 5044 Tree 树链剖分
- hdu 5044 Tree(树链剖分)
- HDU 5044 Tree --树链剖分
- HDU 5044 Tree (树链剖分)
- HDU 5044 Tree(树链剖分)