[HDU5029][树链剖分][线段树]Relief grain[好题]
来源:互联网 发布:linux 命令 编辑:程序博客网 时间:2024/05/07 12:33
题意:
给定由
题解:
一看到“树”和“链”,十有八九是树链剖分。
其实树链剖分也是一种普通的树形转线形,只不过它的想法是:我把每条链都能剖成一些转为线形之后的连续区间。
所以这道题的做法是,树链剖分后,对于每个重链上的区间,在dfs序小的那一个上标记“加上
(不要随便看代码。不要随便看代码。不要随便看代码。重要的事情说三遍。)
#ifndef ONLINE_JUDGE# include "stdafx.h"# pragma warning(disable:4996)#endif#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;//Global Variables & Definitions#define MS(arr, x) memset(arr, x, sizeof(arr))int N, M;#define MAXN 100010#define MAXM 100010#define MAXE 200020#define MAXT 400040#define MAXA 6000030#define LL 1#define RR 100010#define DEFINE_MID int mid = (l + r) >> 1#define lson (u << 1)#define rson (u << 1 | 1)//End Global Variables & Definitions//Mapstruct edge { int v, next;} e[MAXE];int ecnt;int h[MAXN];inline void init_edge() { MS(h, ecnt = -1);}inline void adde(int u, int v) { ++ecnt; e[ecnt].v = v; e[ecnt].next = h[u]; h[u] = ecnt;}//End Map//Segment Treeint maxv[MAXT], maxc[MAXT];void PushUp(int u) { if (!maxv[lson] && !maxv[rson]) { maxv[u] = maxc[u] = 0; } else { if (maxv[rson] > maxv[lson]) { maxv[u] = maxv[rson]; maxc[u] = maxc[rson]; } else { maxv[u] = maxv[lson]; maxc[u] = maxc[lson]; } }}void Build(int u, int l, int r) { maxv[u] = maxc[u] = 0; if (l == r) return; DEFINE_MID; Build(lson, l, mid); Build(rson, mid + 1, r);}void Change(int u, int l, int r, int p, int v) { if (l == r) { maxv[u] += v; maxc[u] = maxv[u] ? l : 0; return; } DEFINE_MID; if (p <= mid) Change(lson, l, mid, p, v); else Change(rson, mid + 1, r, p, v); PushUp(u);}int Query(int u, int l, int r, int p) { if (l == r) return maxv[u]; DEFINE_MID; if (p <= mid) return Query(lson, l, mid, p); else return Query(rson, mid + 1, r, p);}//End Segment Tree//Treeint ans[MAXN];int l[MAXN], r[MAXN], f[MAXN];int hs[MAXN], ha[MAXN];int d[MAXN], size[MAXN];int vis[MAXN];int p[MAXN], who[MAXN];int Acth[MAXN][2];void pre_dfs_A() { MS(r, -1); MS(vis, 0);}void dfs_A(int u, int depth) { Acth[u][0] = Acth[u][1] = -1; vis[u] = 1; d[u] = depth++; size[u] = 1; int ths = -1, thss = -1, v, ptr = l[u] = -1; for (int i = h[u]; ~i; i = e[i].next) if (!vis[v = e[i].v]) { if (~ptr) ptr = r[ptr] = v; else ptr = l[u] = v; f[v] = u; dfs_A(v, depth); if (size[v] > thss) { thss = size[v]; ths = v; } size[u] += size[v]; } hs[u] = ths;}void pre_dfs_B() { ha[1] = 1;}void dfs_B(int u, int & s) { p[u] = s; who[s] = u; ++s; int ths = hs[u]; if (!~ths) return; ha[ths] = ha[u]; dfs_B(ths, s); for (int i = l[u]; ~i; i = r[i]) if (i != ths) { ha[i] = i; dfs_B(i, s); }}struct Act { int v, next;} A[MAXA];int acnt;inline void init_acts() { acnt = -1;}inline void adda(int u, int d, int v) { ++acnt; A[acnt].v = v; A[acnt].next = Acth[u][d]; Acth[u][d] = acnt;}void Update(int u, int v, int c) { int uf, vf; while (u != v) { uf = ha[u]; vf = ha[v]; if (uf == vf) { if (d[u] > d[v]) swap(u, v); adda(u, 0, c); adda(v, 1, c); return; } else { if (d[uf] < d[vf]) { swap(uf, vf); swap(u, v); } adda(uf, 0, c); adda(u, 1, c); u = f[uf]; } } adda(u, 0, c); adda(u, 1, c);}void pre_dfs_C() { Build(1, LL, RR);}void dfs_C(int u) { for (int i = Acth[u][0]; ~i; i = A[i].next) Change(1, LL, RR, A[i].v, 1); ans[u] = maxc[1]; for (int i = Acth[u][1]; ~i; i = A[i].next) Change(1, LL, RR, A[i].v, -1); int ths = hs[u]; if (!~ths) return; dfs_C(ths); for (int i = l[u]; ~i; i = r[i]) if (i != ths) dfs_C(i);}//End Tree//Main Structureinline void ir() { //Build Tree int u, v; init_edge(); for (int i = 1; i < N; ++i) { scanf("%d%d", &u, &v); adde(u, v); adde(v, u); } pre_dfs_A(); dfs_A(1, 0); int temp = 1; pre_dfs_B(); dfs_B(1, temp);}inline void solve() { ir(); //Deal Acts init_acts(); int u, v, c; for (int i = 0; i < M; ++i) { scanf("%d%d%d", &u, &v, &c); Update(u, v, c); } pre_dfs_C(); dfs_C(1); for (int i = 1; i <= N; ++i) printf("%d\n", ans[i]);}int main() { while (scanf("%d%d", &N, &M) == 2 && N) solve(); return 0;}
0 0
- [HDU5029][树链剖分][线段树]Relief grain[好题]
- HDU5029 Relief grain(树链剖分+线段树)
- hdu5029 Relief grain 点权树链剖分,线段树
- hdu5029 Relief grain (树链剖分)
- HDU5029--Relief grain(树链剖分)
- hdu 5029 Relief grain (树链剖分+线段树)
- hdu 5029 Relief grain(树链剖分+线段树)
- HDU 5029Relief grain(树链剖分+线段树)
- HDU 5029Relief grain 树链剖分 好题
- HDU5029 Relief grain 树链剖分+差分统计答案
- HDU 5029 Relief grain 树链剖分+线段树离线维护
- HDU 5209 Relief grain 解题报告(树链剖分 + 线段树)
- HDU 5029 Relief grain 树链剖分 离线 线段树
- HDU 5029 Relief grain (树链剖分 + 线段树)
- [HDU 5029] Relief grain (树链剖分+线段树)
- HDU 5029 Relief grain(恶心的树链剖分 + 线段树)
- HDU 5029Relief grain-树链剖分+线段树+离线
- HDU 5029 Relief grain --树链剖分第一题
- 二元关系的矩阵和图表示
- CV会议+领先研究室+专家+代码网址
- 下载网盘文件失败的解决方法
- 蓝桥杯决赛真题——古代赌局
- git cmd list 2
- [HDU5029][树链剖分][线段树]Relief grain[好题]
- 使用evel()函数将json字符串转换为json对象
- 第一章 转自DQ_DM
- Java 动态代理
- Hackthissite Javascript-Writeup
- DataGridView出现大红叉--在使用多线程访问数据源时
- git cmd list 3
- Linux如何安装redis
- 线段树区间更新,区间统计 poj 2777 Count Color