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. MyBatis源码解析之日志记录

    一 .概述 MyBatis没有提供日志的实现类,需要接入第三方的日志组件,但第三方日志组件都有各自的Log级别,且各不相同,但MyBatis统一提供了trace.debug.warn.error四个级 ...

  2. Hibernate初学

    什么是Hibernate? Hibernate,翻译过来是冬眠的意思,正好现在已经进入秋季,世间万物开始准备冬眠了.其实对于对象来说就是持久化. 我们从三个角度理解一下Hibernate: 一.Hib ...

  3. 解决ie6、ie7下float为right换行的情况

    IE6下有不少奇怪的Bug,今天就碰到一个,float:right换行bug,情况是并列的几个块级元素如div和span,一些设置了左浮动一些设置右浮动,一行的宽度足够放下所有的块级元素,但此时ie6 ...

  4. 百度 echarts K线图使用

    看个效果图先 首先在需要插入图例的HTML中嵌入 <div id="main" style="height:400px"></div> ...

  5. ASP.NET SignalR-B.S/C.S 相互打通DEMO

    ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.   什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知 ...

  6. Web 系统架构一般组成

    负载层技术       负载分配层,是单指利用软件实现的计算机系统上的狭义负载均衡.它是根据业务形态设计一种架构方式,将来自外部客户端的业务请求分担到每一个可用的业务节点上 . 1.用户终端不只包括类 ...

  7. [转]Linux内核最新的连续内存分配器(CMA)——避免预留大块内存

    http://blog.csdn.net/21cnbao/article/details/7309757 在我们使用ARM等嵌入式Linux系统的时候,一个头疼的问题是GPU,Camera,HDMI等 ...

  8. 切换Fragment时实现数据保持

    摘要 Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用.可以将Fragment看作是一个可以嵌入布局中的activity,有自己 ...

  9. 2cmd 窗口 javac 错误:编码GBK的不可映射字符

    错误截图: 解决办法:第一步 第二步:

  10. AWS CSAA -- 02 AWS - 10000 Feet Overview

    004 The History Of AWS So Far 005 AWS - 10000 Foot Overview 006 AWS - 10000 Foot Overview 007 AWS - ...