HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029
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.
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.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> PII; const int MAXV = ;
const int MAXE = MAXV << ;
const int MAXT = MAXV << ; int head[MAXV], ecnt;
int to[MAXE], next[MAXE];
int n, m, maxz; void init() {
memset(head + , -, n * sizeof(int));
ecnt = ;
} void add_edge(int u, int v) {
to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
} #define mid ((l + r) >> 1)
struct Node {
Node *lson, *rson;
int val, cnt, size;
Node() {
val = cnt = size = ;
}
void update() {
Node *s = lson->cnt >= rson->cnt ? lson : rson;
val = s->val;
cnt = s->cnt;
size = lson->size + rson->size;
}
} *nil;
Node statePool[MAXT * ];
Node *stk[MAXT * ];
int top, scnt; Node* new_node() {
Node *p;
if(top) p = stk[--top];
else p = &statePool[scnt++];
p->lson = p->rson = nil;
p->val = p->cnt = p->size = ;
return p;
} void del_node(Node *p) {
stk[top++] = p;
} void remove(Node *y) {
if(y->lson != nil) remove(y->lson);
if(y->rson != nil) remove(y->rson);
del_node(y);
} void modify(Node *&x, int l, int r, int pos, int val) {
if(x == nil) x = new_node();
if(l == r) {
x->val = l;
x->cnt += val;
x->size = (x->cnt > );
} else {
if(pos <= mid) modify(x->lson, l, mid, pos, val);
if(mid < pos) modify(x->rson, mid + , r, pos, val);
x->update();
}
} void merge(Node *x, Node *y, int l, int r) {
if(y->size != ) {
if(l == r) {
modify(x, , maxz, l, y->cnt);
} else {
merge(x, y->lson, l, mid);
merge(x, y->rson, mid + , r);
}
}
} Node* merge(Node *x, Node *y) {
if(x->size < y->size) swap(x, y);
merge(x, y, , maxz);
remove(y);
return x;
} vector<PII> query[MAXV];
struct Modify {
int u, v, c, lca;
void read(int i) {
scanf("%d%d%d", &u, &v, &c);
maxz = max(maxz, c);
query[u].push_back(make_pair(v, i));
query[v].push_back(make_pair(u, i));
}
} ask[MAXV];
int fa[MAXV];
bool vis[MAXV]; int find_set(int x) {
return fa[x] == x ? x : fa[x] = find_set(fa[x]);
} void lca(int u, int f) {
for(int p = head[u]; ~p; p = next[p]) {
int &v = to[p];
if(v == f || vis[v]) continue;
lca(v, u);
fa[v] = u;
}
vis[u] = true;
for(vector<PII>::iterator it = query[u].begin(); it != query[u].end(); ++it) {
if(vis[it->first]) {
ask[it->second].lca = find_set(it->first);
}
}
} vector<PII> pre[MAXV], nxt[MAXV];
int ans[MAXV]; Node* dfs(int u, int f) {
Node *x = new_node();
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(v == f) continue;
x = merge(x, dfs(v, u));
}
for(vector<PII>::iterator it = pre[u].begin(); it != pre[u].end(); ++it)
modify(x, , maxz, it->first, it->second);
ans[u] = x->val;
for(vector<PII>::iterator it = nxt[u].begin(); it != nxt[u].end(); ++it)
modify(x, , maxz, it->first, it->second);
return x;
} void solve() {
for(int i = ; i <= n; ++i) {
fa[i] = i;
vis[i] = false;
pre[i].clear(); nxt[i].clear();
}
lca(, );
for(int i = ; i < m; ++i) {
const Modify &t = ask[i];
pre[t.u].push_back(make_pair(t.c, ));
pre[t.v].push_back(make_pair(t.c, ));
pre[t.lca].push_back(make_pair(t.c, -));
nxt[t.lca].push_back(make_pair(t.c, -));
}
top = scnt = ;
Node *p = dfs(, );
if(p != nil) remove(p); for(int i = ; i <= n; ++i)
printf("%d\n", ans[i]);
} int main() {
nil = new Node();
nil->lson = nil->rson = nil; while(scanf("%d%d", &n, &m) != EOF) {
if(n == && m == ) break;
init();
for(int i = , u, v; i < n; ++i) {
scanf("%d%d", &u, &v);
add_edge(u, v);
}
for(int i = ; i <= n; ++i) query[i].clear();
maxz = ;
for(int i = ; i < m; ++i) ask[i].read(i);
solve();
}
}
HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)的更多相关文章
- HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)
Problem Description Mex is a function on a set of integers, which is universally used for impartial ...
- HDU 4719 Oh My Holy FFF(DP+线段树)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
Description N soldiers from the famous "*FFF* army" is standing in a line, from left to ri ...
- HDU 5052 Yaoge’s maximum profit 光秃秃的树链拆分 2014 ACM/ICPC Asia Regional Shanghai Online
意甲冠军: 特定n小点的树权. 以下n每一行给出了正确的一点点来表达一个销售点每只鸡价格的格 以下n-1行给出了树的侧 以下Q操作 Q行 u, v, val 从u走v,程中能够买一个鸡腿,然后到后面卖 ...
- hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi'an Online)
Mart Master II Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)
Barricade Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)
Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge wat ...
- HDU 5002 Tree(动态树LCT)(2014 ACM/ICPC Asia Regional Anshan Online)
Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node ...
- HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)
Problem Description Zero and One are good friends who always have fun with each other. This time, ...
- HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 Problem Description Today we play a squiggly sud ...
随机推荐
- Bluetooth Security Manager
一.概念 The Security Manager defines methods of pairing and key distribution, a protocol for those ...
- Java迭代 : Iterator和Iterable接口
从英文意思去理解 Iterable :故名思议,实现了这个接口的集合对象支持迭代,是可迭代的.able结尾的表示 能...样,可以做.... Iterator: 在英语中or 结尾是都是表示 .. ...
- [LeetCode]题解(python):049-Groups Anagrams
题目来源 https://leetcode.com/problems/anagrams/ Given an array of strings, group anagrams together. For ...
- MVC4怎么设置@Html.TextBox这样的输入框的css样式
在mvc中 @Html.TextBox("txtCode","",new {@class="code",style="width: ...
- JavaScript实现在textbox输入时自动去数据库匹配并找出类似值列出,选择后记得将值填入本textbox及下一个textbox
1. <script src='<%= Application["rootURL"] %>JS/jquery-1.4.1.min.js' type="t ...
- SEO优化笔记
1,清理垃圾代码. 清理垃圾代码是指删除页面中的冗余代码,可以删除80%的冗余代码,垃圾代码主要指那些删除了也不会对页面有任何影响的非必要代码.最常见的垃圾代码:空格空格字符是网页中最常见的垃圾代码. ...
- php数组遍历
<?php $arr = array('a','b','c','d','e','f'); //for语句只能遍历索引数组 for($i = 0; $i < 6; $i++){ echo $ ...
- SqlServer基础:游标
记录下今天用到的游标: DECLARE @TempID INTDECLARE @Number INTSET @Number=1DECLARE myCursor CURSOR FOR SELEC ...
- JavaScript基础总结三部曲之一
JavaScript是一种基于对象的编程语言,基于对象指的是所有的对象已经由浏览器提供好了,用户直接使用就可以了. 另外,JS是嵌入在HTML语法之中的编程语言. PS:虽然是基于对象的语言,但是 ...
- dataguard集群搭建
dataguard集群搭建 1. 创建虚拟机 创建一台虚拟机配置如下: 系统Red Hat Enterprise 6(64位).16vCPU.8G内存.两块VM Network类型网卡.三块硬盘分别为 ...