HDU 5029 Relief grain
来源:互联网 发布:锦尚中国源码论坛 编辑:程序博客网 时间:2024/05/21 11:26
题意:
一棵树 m次染色 每次染色一条路径 颜色不会覆盖会积累 问每个点覆盖次数最多的颜色是什么
思路:
树上路径操作不是树链剖分就是LCT 对于每次染色 相当于让那种颜色的权值+1
一般的熟练剖分都是将树剖成线段然后放在线段树上 这题只是剖成线段 然后对于路径的染色 就变成了对多个线段的染色
由于剖分已经使树变成了线性的结构 因此我们可以利用“头加尾减”的方式维护 即 如果染色[u,v]那么u处++然后v+1处--
由于本题有多种颜色 为了快速解决区间更新和求最大值问题我们需要使用线段树 即维护权值线段树 然后从头到尾扫一遍即可
代码:
#pragma comment(linker,"/STACk:10240000,10240000")#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<cassert>#include<vector>#include<set>#include<map>#include<queue>using namespace std;typedef long long LL;#define N 100010#define L(x) (x<<1)#define R(x) ((x<<1)|1)#define MI(x,y) ((x+y)>>1)int n, m, tot, idx;int head[N], pre[N], size[N], dep[N], hson[N], top[N], tid[N], ftid[N], ans[N];struct Edge {int u, v, next;} ed[N * 2];struct Add {int c, v, next;} ad[N * 40];struct Tree {int l, r, v;} d[N * 4];void addedge(int u, int v) {ed[tot].u = u;ed[tot].v = v;ed[tot].next = head[u];head[u] = tot++;}void add(int u, int c, int v) {ad[tot].c = c;ad[tot].v = v;ad[tot].next = head[u];head[u] = tot++;}void dfs1(int u, int fa) {pre[u] = fa;size[u] = 1;dep[u] = dep[fa] + 1;hson[u] = 0;for (int i = head[u]; ~i; i = ed[i].next) {int v = ed[i].v;if (v != fa) {dfs1(v, u);if (size[v] > size[hson[u]])hson[u] = v;size[u] += size[v];}}}void dfs2(int u, int tp) {tid[u] = idx;ftid[idx] = u;idx++;top[u] = tp;if (hson[u])dfs2(hson[u], tp);for (int i = head[u]; ~i; i = ed[i].next) {int v = ed[i].v;if (v != pre[u] && v != hson[u])dfs2(v, v);}}void Update(int u, int v, int c) {int fu = top[u], fv = top[v];while (fu != fv) {if (dep[fu] >= dep[fv]) {add(tid[fu], c, 1);add(tid[u] + 1, c, -1);u = pre[fu];fu = top[u];} else {add(tid[fv], c, 1);add(tid[v] + 1, c, -1);v = pre[fv];fv = top[v];}}if (dep[u] > dep[v])swap(u, v);add(tid[u], c, 1);add(tid[v] + 1, c, -1);}void build(int l, int r, int i) {d[i].l = l;d[i].r = r;d[i].v = 0;if (l == r)return;int mid = MI(l,r);build(l, mid, L(i));build(mid + 1, r, R(i));}void up(int i) {d[i].v = max(d[L(i)].v, d[R(i)].v);}void update(int p, int i, int v) {if (d[i].l == d[i].r) {d[i].v += v;return;}int mid = MI(d[i].l,d[i].r);if (p <= mid)update(p, L(i), v);elseupdate(p, R(i), v);up(i);}int query(int i) {if (d[i].l == d[i].r)return d[i].l;if (d[i].v == d[L(i)].v)return query(L(i));elsereturn query(R(i));}int main() {int i, u, v, c;while (~scanf("%d%d", &n, &m)) {if (!n && !m)break;tot = 0;memset(head, -1, sizeof(head));for (i = 1; i < n; i++) {scanf("%d%d", &u, &v);addedge(u, v);addedge(v, u);}dfs1(1, 0);idx = 1;dfs2(1, 1);tot = 0;memset(head, -1, sizeof(head));for (i = 1; i <= m; i++) {scanf("%d%d%d", &u, &v, &c);Update(u, v, c);}build(0, 100001, 1);for (u = 1; u <= n; u++) {for (i = head[u]; ~i; i = ad[i].next)update(ad[i].c, 1, ad[i].v);ans[ftid[u]] = query(1);}for (i = 1; i <= n; i++) {printf("%d\n", ans[i]);assert(ans[i] >= 0 && ans[i] <= 100000);}}return 0;}
0 0
- HDU 5029 Relief grain
- hdu 5029 Relief grain
- hdu 5029 Relief grain(树链剖分好题)
- hdu 5029 Relief grain 树链剖分
- hdu 5029 Relief grain 树链剖分
- hdu 5029 Relief grain 树剖
- hdu 5029 Relief grain(树链剖分好题)
- Hdu 5029 Relief grain(树链剖分)
- hdu 5029 Relief grain (树链剖分+线段树)
- hdu 5029 Relief grain(树链剖分+线段树)
- HDU 5029 Relief grain(树链剖分)
- HDU 5029 Relief grain --树链剖分第一题
- HDU 5029Relief grain 树链剖分 好题
- HDU 5029Relief grain(树链剖分+线段树)
- HDOJ 5029 Relief grain
- 【HDU】5029 Relief grain 树链剖分+离线标记法
- HDU 5029 Relief grain 树链剖分+线段树离线维护
- HDU 5029 Relief grain 树链剖分 离线 线段树
- OpenCV基础篇之查找表
- 【字符串hash】 codeforces 471D MUH and Cube Walls
- CentOS上编译安装OpenCV-2.3.1与ffmpeg-2.1.2
- leetcode-Sudoku Solver
- hackerrank The Love-Letter Mystery
- HDU 5029 Relief grain
- OpenCV基础篇之读取显示图片
- 新入职的程序员
- android shape的使用
- OpenCV基础篇之像素操作对比度调节
- linux内存管理内幕
- 属性动画是如何工作的?
- LTE:上行定时提前(一)
- position