题目描述:

H - Relief grain
Time Limit:5000MS Memory Limit:100000KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

HDU 5029
Appoint description:
Description
The soil is cracking up because of the drought and the rabbit kingdom is facing a serious famine. The RRC(Rabbit Red Cross) organizes the distribution of relief grain in the disaster area.

We can regard the kingdom as a tree with n nodes and each node stands for a village. The distribution of the relief grain is divided into m phases. For each phases, the RRC will choose a path of the tree and distribute some relief grain of a certain type for every village located in the path.

There are many types of grains. The RRC wants to figure out which type of grain is distributed the most times in every village.

Input
The input consists of at most 25 test cases.

For each test case, the first line contains two integer n and m indicating the number of villages and the number of phases.

The following n-1 lines describe the tree. Each of the lines contains two integer x and y indicating that there is an edge between the x-th village and the y-th village.

The following m lines describe the phases. Each line contains three integer x, y and z indicating that there is a distribution in the path from x-th village to y-th village with grain of type z. (1 <= n <= 100000, 0 <= m <= 100000, 1 <= x <= n, 1 <= y <= n, 1 <= z <= 100000)

The input ends by n = 0 and m = 0.

Output
For each test case, output n integers. The i-th integer denotes the type that is distributed the most times in the i-th village. If there are multiple types which have the same times of distribution, output the minimal one. If there is no relief grain in a village, just output 0.

Sample Input
2 4
1 2
1 1 1
1 2 2
2 2 2
2 2 1
5 3
1 2
3 1
3 4
5 3
2 3 3
1 5 2
3 3 3
0 0

Sample Output
1
2
2
3
3
0
2
Hint
For the first test case, the relief grain in the 1st village is {1, 2}, and the relief grain in the 2nd village is {1, 2, 2}.

题解:

和队友在比赛的时候想出来了还是略开心啊(⊙o⊙).
发现总共修改了1e5次,如果每一次我们只用很少的点来描述这次修改,那么就不会爆内存.于是想到就像差分一样打两个点,一个add Z 一个 sub Z,但是树上的链不是线性的,于是用树链剖分,把一个链变成了<=2*log个线性的链,然后在链上类似于差分打点. 最后算结果的时候一起算一次,用一个线段树来维护结果.

重点:

观察到可以用很少的点来描述修改,因为整道题目只算了一次答案,所以我们可以差分着打点.
然后发现如果用dfs序的树链剖分就比较好写,因为变成线性的啦.

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>using namespace std;const int maxn = 1e5 + 100;
const int MAX_NODE = 4*maxn + 100;
const int MAX_T = 5e6+100;
const int maxZ = 100000;int fa[maxn], son[maxn], num[maxn], top[maxn], deep[maxn], getno[maxn], fanno[maxn], tot;
vector<int> G[maxn];
//vector<int> add[maxn], sub[maxn];
struct vec
{int head[maxn], nxt[MAX_T], id[MAX_T];int tot;void addEdge(int a, int z){nxt[tot] = head[a];id[tot] = z;head[a] = tot;tot++;}
};
vec add, sub;
int ans[maxn];
int n, M;
struct info
{int num, id;info(int _num = 0, int _id = 0){num = _num;id = _id;}
};
info tree[MAX_NODE];
info getMerge(info a, info b)
{if(a.num > b.num)return a;if(b.num > a.num)return b;if(b.id < a.id)return b;return a;
}
void pushUp(int rt)
{int lrt = (rt<<1), rrt = lrt+1;if(tree[rrt].num > tree[lrt].num){tree[rt] = tree[rrt];}else{tree[rt] = tree[lrt];}
}
void initail(int rt, int l, int r)
{if(l==r){tree[rt].num = 0;tree[rt].id = l;return;}int lrt = (rt<<1), rrt = lrt+1, m = (l+r)/2;initail(lrt, l, m);initail(rrt, m+1, r);pushUp(rt);
}
void change(int pos, int val, int rt, int l, int r)
{if(pos==l&&pos==r){tree[rt].num += val;return;}int lrt = (rt<<1), rrt = lrt+1, m = (l+r)/2;if(pos <= m){change(pos, val, lrt, l, m);}else{change(pos, val, rrt, m+1, r);}pushUp(rt);
}
info query(int L, int R, int rt, int l, int r)
{if(L <= l && R >= r){return tree[rt];}info t;t.num = -1;int lrt = (rt<<1), rrt = lrt+1, m = (l+r)/2;if(L <= m){info tmp = query(L, R, lrt, l, m);t = getMerge(t, tmp);}if(R >= m+1){info tmp = query(L, R, rrt, m+1, r);t = getMerge(t, tmp);}return t;
}void dfs_first(int u, int pa)
{num[u] = 1;son[u] = 0;for(int i = 0;i<G[u].size();i++){int v = G[u][i];if(v!=pa){fa[v] = u;deep[v] = deep[u]+1;dfs_first(v, u);if(num[v] > num[son[u]]){son[u] = v;}num[u] += num[v];}}
}
void dfs_second(int u, int tp)
{tot++;getno[u] = tot;fanno[tot] = u;top[u] = tp;if(son[u] != 0){dfs_second(son[u], tp);}for(int i = 0;i<G[u].size();i++){int v = G[u][i];if(v!=fa[u] && v!=son[u]){dfs_second(v, v);}}
}
void gao(int l, int r, int z)
{add.addEdge(l, z);//add[l].push_back(z);
//    if(r < n)
//        sub[r+1].push_back(z);if(r < n)sub.addEdge(r+1, z);
}
void change(int a, int b, int z)
{int tpa = top[a], tpb = top[b];while(tpa!=tpb){if(deep[tpa] < deep[tpb]){swap(tpa, tpb);swap(a, b);}gao(getno[tpa], getno[a], z);a = fa[tpa];tpa = top[a];}if(deep[a] < deep[b])swap(a, b);gao(getno[b], getno[a], z);
}void solve()
{num[0] = 0;fa[1] = 0;deep[1] = 0;dfs_first(1, 0);tot = 0;dfs_second(1, 1);for(int i = 1;i<=n;i++){add.head[i] = -1;sub.head[i] = -1;}add.tot = 0;sub.tot = 0;//printf("*******%d\n", tot);for(int i = 1;i<=M;i++){int x, y, z;scanf("%d%d%d", &x, &y, &z);change(x, y, z);}initail(1, 1, maxZ);for(int i = 1;i<=n;i++){for(int j = add.head[i];j!=-1;j = add.nxt[j]){int num = add.id[j];change(num, 1, 1, 1, maxZ);}for(int j = sub.head[i];j!=-1;j = sub.nxt[j]){int num = sub.id[j];change(num, -1, 1, 1, maxZ);}info t = query(1, maxZ, 1, 1, maxZ);if(t.num==0){ans[fanno[i]] = 0;}else{ans[fanno[i]] = t.id;}}for(int i = 1;i<=n;i++){printf("%d\n", ans[i]);}
}int main()
{//freopen("Hin.txt", "r", stdin);while(scanf("%d%d", &n, &M) != EOF){if(n==0&&M==0)break;for(int i = 1;i<=n;i++)G[i].clear();for(int i = 1;i<=n-1;i++){int a, b;scanf("%d%d", &a, &b);G[a].push_back(b);G[b].push_back(a);}solve();}return 0;
}

H - Relief grain相关推荐

  1. [树链剖分]List wants to travel,Relief grain,hotel加强版,This world need more Zhu

    文章目录 B:Relief grain C:hotel加强版 B:Relief grain 题目 将一段区间修改的标记变成差分,每次都是连续一段的dfndfndfn序修改 从小到大枚举dfndfndf ...

  2. 树链剖分(维护树上信息)

    学习前请先掌握线段树:线段树(维护区间信息) 一,思想: 将一颗树拆成多条线性链以方便维护(如线段树). 先给出以下定义(通过这些定义我们就可以组成链): 重儿子:子节点最多的儿子就是重儿子 轻儿子: ...

  3. 浅谈关于特征选择算法与Relief的实现

    一. 背景 1) 问题 在机器学习的实际应用中,特征数量可能较多,其中可能存在不相关的特征,特征之间也可能存在相关性,容易导致如下的后果: 1.     特征个数越多,分析特征.训练模型所需的时间就越 ...

  4. FFmpeg视频转码技巧之-crf参数(H.264篇)

    昨天,有个朋友给我出了个难题:他手上有一个视频,1080P的,49秒,200多兆:要求在确保质量的情况下把文件压缩到10M以内. 这是什么概念呢?按照文件大小10M来计算,码率是:10 x 8 / 4 ...

  5. x264 - 高品质 H.264 编码器

    H.264 / MPEG-4 AVC 是优秀的视讯编码格式 就目前已成熟的视讯编码格式而言,H.264的压缩率是最佳的. 压缩率极高,可以只用很低 bitrate 提供堪用画质. 而 x264 为免费 ...

  6. x264学习----x264.h结构体

    x264.h结构体学习,还在持续更新中 /****************************************************************************** ...

  7. Relief特征提取算法实战

    简介及其演变 Relief算法最早由Kira提出,最初局限于两类数据的分类问题.Relief算法是一种特征权重算法(Feature weighting algorithms),根据各个特征和类别的相关 ...

  8. 西瓜书课后11.1(Relief算法)

    题目 试编程实现Relief算法,并考察其在西瓜数据集3.0上的运行结果. 分析 Relief是一种过滤式特征选择方法.简单来说就是利用这种方法可以计算出各个特征子集的重要性.我们用 δ j \del ...

  9. Feature Selection详解(附带Relief、Relief-F、LVM详解)(一)

    Feature Selection详解 第二十五次写博客,本人数学基础不是太好,如果有幸能得到读者指正,感激不尽,希望能借此机会向大家学习.这一篇主要是针对特征选择问题的几种常见方法进行阐述,并介绍其 ...

最新文章

  1. python安装成功的图标_ubuntu下:安装anaconda、环境配置、软件图标的创建、成功启动anaconda图形界面...
  2. UIProgressView(进度条控件)
  3. Logica实战与剖析(1)
  4. Maven(四):定制库到Mave本地资源库 (Kaptcha)
  5. 案例:无人测量船水库水下地形测量及库容量计算
  6. python打印九九加法表_Python小脚本
  7. java.lang.IllegalArgumentException: node to traverse cannot be null! HQL语法问题
  8. 一文搞懂软件测试,完整总结软件测试基础知识
  9. 使用JSON和Jersey的Java RESTful Web服务
  10. MATLAB【工具箱下载】汇总
  11. 如何从uboot中推算路由器flash烧写地址
  12. SQLite3介绍及SQL语句详解(SQLite一)
  13. UE4入门实例31(Unreal制作炫酷高效黑洞粒子)
  14. 纸张的规格A3.A4.A5.A6纸的尺寸大小
  15. android录制屏幕接口,ARDC Android 远程桌面助手 录屏 演示 MD
  16. 丁火生于未月命理分析_日主丁、未月出生五行喜用分析-丁日未月生《晶灵八字算命》...
  17. MIT 黑科技:通过脑电波和手势控制机器人
  18. C/C++刁钻问题各个击破之细说sizeof .
  19. [电脑问题1]Microsoft Visual Basic运行时错误‘-2147221164’:没有注册类
  20. 为什么游戏需要热更新?

热门文章

  1. 机器人瓦力有什么西方的风格_机器人瓦力中英文对照影评
  2. 啥子是volatile
  3. 谁能够最终实现超越普通计算机的“量子霸权”
  4. k3595参数_1高频三极管的一些型号及参数
  5. 数字时钟程序c语言,C语言实现电子时钟程序
  6. android 汉字 unicode编码,Android解析UniCode编码
  7. 国际碳行动伙伴组织(ICAP)全球碳市场进展资料2019
  8. k8s搭建drone
  9. 开源项目之杀毒软件 clamwin
  10. 对当下很火的两大短视频平台 抖音 和 微视进行竞品分析