Relief grain

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others)
Total Submission(s): 3246    Accepted Submission(s): 955


题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5029

Problem 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}.

 

Source

 

题意

给你一棵树,每次可以给一条路径分配一个值,值可以叠加,最后输出每个点被分配最多的那个值。
 

题解

我们先考虑一个问题,如果是在一个序列里,每次给你一个区间(l,r),问每个点最后被多少个区间覆盖。
这道题是一道比较经典的扫描线的题,如果不会我来讲讲:
对于每个区间(l,r),我们把他拆成两个点,(l,1) 和(r+1,-1),(1代码左端点,-1表示右端点),并将其排序。然后假想有一条扫描线从左扫到右,每次碰到一个左端点答案加一,碰到右端点答案减一。
边扫边统计答案,答案就是到当前点,有多少个左端点还没有碰到右端点。
这样可能有点抽象自己可以模拟几遍,应该还是能想出来的。
 
那么和这道题有什么关系呢? 当然有关系啦,不然我为什么会将呢?
1.我们加一颗权值线段树,对于每个区间我们增加了一维权值来确定,即(l,r,val)表示l~r赋值为val,那么还是如上一样扫描,然后答案加一的步骤改成给线段树点val加上1,
这样每个点的答案就是线段树中最大值的位置。
 
2.但是这是在树上,所以树链剖分将他变成一个连续序列即可。
 

代码

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200050
struct Edge{int from,to,s;}edges[N<<];
struct Query
{
int x,val,id;
bool operator <(const Query&b)const
{return x<b.x;}
}a[N<<];
struct Tree{int l,r,mx,wmx;}tr[N<<];
int n,m,num,ans[N];
int tot,last[N];
int cnt,fa[N],dp[N],size[N],son[N],rk[N],kth[N],top[N];
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void AddEdge(int x,int y)
{
edges[++tot]=Edge{x,y,last[x]};
last[x]=tot;
}
void dfs1(int x,int pre)
{
fa[x]=pre;
dp[x]=dp[pre]+;
size[x]=;
son[x]=;
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dfs1(e.to,x);
size[x]+=size[e.to];
if (size[e.to]>size[son[x]])
son[x]=e.to;
}
}
void dfs2(int x,int y)
{
rk[x]=++cnt;
kth[cnt]=x;
top[x]=y;
if (son[x]==)return;
dfs2(son[x],y);
for(int i=last[x];i;i=edges[i].s)
{
Edge e=edges[i];
if (e.to==fa[x]||e.to==son[x])continue;
dfs2(e.to,e.to);
}
}
void push_up(Tree &c,Tree a,Tree b)
{
c.mx=max(a.mx,b.mx);
c.wmx=c.mx==a.mx?a.wmx:b.wmx;
}
void bt(int x,int l,int r)
{
tr[x]=Tree{l,r,,};
if (l==r){tr[x].wmx=l;return;}
int mid=(l+r)>>;
bt(x<<,l,mid);
bt(x<<|,mid+,r);
}
void update(int x,int p,int tt)
{
if (p<=tr[x].l&&tr[x].r<=p)
{
tr[x].mx+=tt;
tr[x].wmx=tr[x].l;
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if (p<=mid)update(x<<,p,tt);
if (mid<p)update(x<<|,p,tt);
push_up(tr[x],tr[x<<],tr[x<<|]);
}
void change(int x,int y,int tt)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if (dp[fx]<dp[fy])swap(x,y),swap(fx,fy);
a[++num]=Query{rk[fx],tt,};
a[++num]=Query{rk[x]+,tt,-};
x=fa[fx];fx=top[x];
}
if (dp[x]<dp[y])swap(x,y);
a[++num]=Query{rk[y],tt,};
a[++num]=Query{rk[x]+,tt,-};
}
void work()
{
read(n); read(m);
if (n==)exit();
for(int i=;i<=n-;i++)
{
int x,y;
read(x); read(y);
AddEdge(x,y);
AddEdge(y,x);
}
dfs1(,);
dfs2(,);
bt(,,);
for(int i=;i<=m;i++)
{
int x,y,tt;
read(x); read(y); read(tt);
change(x,y,tt);
}
sort(a+,a+num+);
for(int i=;i<=num-;i++)
{
int l=a[i].x;
update(,a[i].val,a[i].id);
while(a[i+].x==a[i].x)
//update(1,a[++i].val,a[i].id);
i++,update(,a[i].val,a[i].id); for(int j=l;j<a[i+].x;j++)
ans[kth[j]]=tr[].wmx;
}
for(int i=;i<=n;i++)printf("%d\n",ans[i]);
}
void clear()
{
tot=; cnt=; num=;
memset(last,,sizeof(last));
memset(ans,,sizeof(ans));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
while()
{
clear();
work();
}
}
 
 

J - Relief grain HDU - 5029的更多相关文章

  1. hdu 5029 Relief grain(树链剖分+线段树)

    题目链接:hdu 5029 Relief grain 题目大意:给定一棵树,然后每次操作在uv路径上为每一个节点加入一个数w,最后输出每一个节点个数最多的那个数. 解题思路:由于是在树的路径上做操作, ...

  2. HDU 5029 Relief grain 树链剖分打标记 线段树区间最大值

    Relief grain Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  3. HDU 5029 Relief grain(离线+线段树+启发式合并)(2014 ACM/ICPC Asia Regional Guangzhou Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029 Problem Description The soil is cracking up beca ...

  4. [HDU 5029] Relief grain

    Relief grain Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others)T ...

  5. J - Super Mario HDU - 4417 线段树 离线处理 区间排序

    J - Super Mario HDU - 4417 这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好. 不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该 ...

  6. HDU 5029 Relief grain --树链剖分第一题

    题意:给一棵树,每次给两个节点间的所有节点发放第k种东西,问最后每个节点拿到的最多的东西是哪种. 解法:解决树的路径上的修改查询问题一般用到的是树链剖分+线段树,以前不会写,后来学了一下树链剖分,感觉 ...

  7. 树链剖分+线段树 HDOJ 5029 Relief grain(分配粮食)

    题目链接 题意: 分粮食我就当成涂色了.有n个点的一棵树,在a到b的路上都涂上c颜色,颜色可重复叠加,问最后每一个点的最大颜色数量的颜色类型. 思路: 首先这题的输出是每一个点最后的情况,考虑离线做法 ...

  8. 树链剖分处理+线段树解决问题 HDU 5029

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5029 题意:n个点的树,m次操作.每次操作输入L,R,V,表示在[L,R]这个区间加上V这个数字.比 ...

  9. J - Air Raid - hdu 1151(最小边覆盖)

    题意:给一个有向无环图,求出来最少需要几个士兵可以遍历所有的边. 分析:有向无环图的最小边覆盖 = 点数 - 最大匹配数 为什么是这样的公式??可以思考一下,如果这N个点之间没有边,是不是应该有N个士 ...

随机推荐

  1. 撩课-Java每天5道面试题第24天

    151.springMVC和struts2的区别有哪些? .springmvc的入口是一个servlet即前端控制器(DispatchServlet), 而struts2入口是一个filter过虑器( ...

  2. HDU 4135 Co-prime 欧拉+容斥定理

    Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  3. mysql行转列,列转行

    行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...

  4. HTML5 number类型文本框step属性的验证机制——张鑫旭

    我在下一盘很大的棋,本文只是其中的一个棋子. 需要提前知道的: 目前而言,对step雄起的浏览器为IE10+, Chrome以及Opera浏览器. 需要预先知道number类型input的一些基本知识 ...

  5. 神奇的Flex 布局

    layout是css中的一个重点.传统的页面布局是盒子模型,依赖 display属性 ,position属性 , float属性.它对于那些特殊布局非常不方便,而且定位用多了会出现挺多的bug. 所以 ...

  6. Python 利用Python编写简单网络爬虫实例3

    利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站“http://bbs.51testing. ...

  7. 分布式部署下的报表调用 API调用 权限问题以及性能方案

     背景描述: 客户的实际情况是需要在具体系统构架前,通过与厂商讨论确定最终的系统架构方案. 需求是客户自己有管理系统,希望建立一个独立的报表服务器,该报表服务器可以对多个管理系统提供报表服务,不知 ...

  8. import依赖范围的使用

    <!-- <parent> <groupId>org.springframework.boot</groupId> <artifactId>spr ...

  9. java 对象

      对象可以看成是静态属性和动态属性的封装体.静态属性——成员变量:动态属性——方法. 1.汇编语言是对机器语言的抽象. 2.面向过程的语言是对汇编语言的抽象.属性和方法分离,不是封装在一起的,复用性 ...

  10. Unity Optimization UNITY优化关注列表

    这里主要罗列Unity引擎进行开发的应用或游戏,可以进行优化的各个关注点.(此文会持续更新) C# GC alloc Update LateUpdate Serialize String ToStri ...