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 ...
随机推荐
- (IOS)Swift2.0 Radio 程序分析
本文主要分享下楼主在学习Swift编程过程中,对GitHub上的一个开源项目Swift Radio的研究心得. 项目地址:https://github.com/swiftcodex/Swift-Rad ...
- MySQL数据库表名、列名、别名区分大小写的问题
MySQL在Linux下数据库名.表名.列名.别名大小写规则是这样的: 1.数据库名与表名是严格区分大小写的: 2.表的别名是严格区分大小写的: 3.列名与列的别名在所有的情况下均是忽略大小写的: 4 ...
- java JDK8 学习笔记——第17章 反射与类加载器
第十七章 反射与类加载器 17.1 运用反射 反射:.class文档反映了类基本信息,从Class等API取得类信息的方式称为反射. 17.1.1 Class与.class文档 1.java.lang ...
- windbg sos版本不匹配问题解决
dumpheap 时提示: 0:105> !dumpheap -stat The garbage collector data structures are not in a valid sta ...
- css“变形”效果
<html <head> <title></title> <style> .test { margin-left:300px; margin-to ...
- Spark Programming--Fundamental operation
max max(key=None) Find the maximum item in this RDD. Parameters:key – A function used to generate ke ...
- 通过CSS使文本框中输入的小写字母变大写字母
在style.css文件中写 .dataField input{text-transform:uppercase;} .dataField textarea {text-transform:upper ...
- apache 根据端口访问配置
1. http.conf 中 需要加上 listen 8080 然后 开启 Include conf/extra/httpd-vhosts.conf http.conf 是项目的主配置文件 ,引 ...
- 利用utl_file来读取文件.
以前写过用external table来加载trace文件,详情参考下面链接. http://www.cnblogs.com/princessd8251/p/3779145.html 今天要做到是用U ...
- C语言:其他进制数转换为十进制(方法一)
#include<stdio.h> #include<math.h> #include<string.h> //其他任意进制转换为十进制 int main() { ...