HDU 5029 Relief grain 树链剖分打标记 线段树区间最大值
Relief grain
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=5029
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
题意
有n个点的树,有m次操作
操作是在x-y的链上的每一个点,都增加一个W
然后让你输出每个点出现次数最多的数是什么
题解:
看到链状,很显然就是树链剖分
我们对于每个询问都按照lca去打上标记,就G[u].push_back(v,1),G[v].push_back(v,-1)这种
打完标记之后,我们再按照树链剖分的顺序去处理这些标记就好了
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <vector>
using namespace std;
const int N=;
const int INF=<<; int n,tim;
vector<pair<int,int> >G[];
long long num[N];
int siz[N],top[N],son[N];
int dep[N],tid[N],Rank[N],fa[N];
int head[N],to[*N],Next[*N],edge;
int flag = ;
struct Edge
{
int u,v;
};
Edge tmp[*N];
int ans[N];
void Init()
{
memset(head,-,sizeof(head));
memset(son,-,sizeof(son));
tim=;
edge=;
for(int i=;i<;i++)
G[i].clear();
memset(ans,,sizeof(ans));
} void addedge(int u,int v)
{
to[edge]=v,Next[edge]=head[u],head[u]=edge++;
to[edge]=u,Next[edge]=head[v],head[v]=edge++;
} //树链剖分部分
void dfs1(int u,int father,int d)
{
dep[u]=d;
fa[u]=father;
siz[u]=;
for(int i=head[u]; ~i; i=Next[i])
{
int v=to[i];
if(v!=father)
{
dfs1(v,u,d+);
siz[u]+=siz[v];
if(son[u]==-||siz[v]>siz[son[u]])
son[u]=v;
}
}
} void dfs2(int u,int tp)
{
top[u]=tp;
tid[u]=++tim;
Rank[tid[u]]=u;
if(son[u]==-) return;
dfs2(son[u],tp);
for(int i=head[u]; ~i; i=Next[i])
{
int v=to[i];
if(v!=son[u]&&v!=fa[u])
dfs2(v,v);
}
} void Do(int l,int r,int x)
{
//cout<<l<<" "<<r<<endl;
G[l].push_back(make_pair(x,));
G[r].push_back(make_pair(x,-));
} void solve(int x,int y,int val)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Do(top[x],x,val);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
Do(x,y,val);
}
/////////////////////////////////////////////////////////线段树 typedef int SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType Max1 , lazy ,Max2;
}; treenode tree[N]; inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].Max1 = ;
tree[o].Max2 = L;
if (R > L)
{
int mid = (L+R) >> ;
build_tree(L,mid,o*);
build_tree(mid+,R,o*+);
}
} inline void updata(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR)
tree[o].Max1 += v;
else
{
int mid = (L+R)>>;
if (QL <= mid) updata(QL,QR,v,o*);
if (QR > mid) updata(QL,QR,v,o*+);
if(tree[o*].Max1>=tree[o*+].Max1)
tree[o].Max1 = tree[o*].Max1,tree[o].Max2 = tree[o*].Max2;
else
tree[o].Max1 = tree[o*+].Max1,tree[o].Max2 = tree[o*+].Max2;
}
} ///////////////////////////////////////////////////
int MM;
void Get(int u,int tp)
{
//cout<<u<<endl;
for(int j=;j<G[u].size();j++)
{
if(G[u][j].second==-)continue;
//cout<<G[u][j].first<<" "<<G[u][j].second<<endl;
updata(G[u][j].first,G[u][j].first,G[u][j].second,);
}
//cout<<u<<" "<<tree[1].Max2<<" flag"<<endl;
ans[u]=tree[].Max2;
for(int j=;j<G[u].size();j++)
{
if(G[u][j].second==)continue;
//cout<<G[u][j].first<<" "<<G[u][j].second<<endl;
updata(G[u][j].first,G[u][j].first,G[u][j].second,);
}
if(son[u]==-) return;
Get(son[u],tp);
for(int i=head[u]; ~i; i=Next[i])
{
int v=to[i];
if(v!=son[u]&&v!=fa[u])
Get(v,v);
}
}
int main()
{
while(scanf("%d%d",&n,&MM)!=EOF)
{
if(n==&&MM==)break;
Init();
for(int i=; i<n; i++)
{
int a,b;
scanf("%d%d",&a,&b);
addedge(a,b);
}
dfs1(,,);
dfs2(,);
while(MM--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
solve(x,y,z);
}
build_tree(,,);
Get(,);
for(int i=;i<=n;i++)
printf("%d\n",ans[i]);
}
return ;
}
HDU 5029 Relief grain 树链剖分打标记 线段树区间最大值的更多相关文章
- BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...
- BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- HDU 3966 Aragorn's Story(模板题)【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一颗带点权的树,进行两种操作,一是给定树上一段路径,对其上每个点的点权增加或者减少一个数,二是对某个编号点的点权进行查询. 解题分析: 树链剖分的模板题,还不 ...
- 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)
题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...
- LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】
题目分析: 好题.本来是一道好的非套路题,但是不凑巧的是当年有一位国家集训队员正好介绍了这个算法. 首先考虑静态的情况.这个的DP方程非常容易写出来. 接着可以注意到对于异或结果的计数可以看成一个FW ...
- HYSBZ 4034 【树链剖分】+【线段树 】
<题目链接> 题目大意: 有一棵点数为 N 的树,以点 1 为根,且树点有权值.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...
- POJ 2763 Housewife Wind 【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一棵无向树,这棵树的有边权,这棵树的边的序号完全由输入边的序号决定.给你一个人的起点,进行两次操作: 一:该人从起点走到指定点,问你这段路径的边权总和是多少. ...
- 焦作网络赛E-JiuYuanWantstoEat【树链剖分】【线段树】
You ye Jiu yuan is the daughter of the Great GOD Emancipator. And when she becomes an adult, she wil ...
- 【树链剖分】【线段树】bzoj3626 [LNOI2014]LCA
引用题解: http://blog.csdn.net/popoqqq/article/details/38823457 题目大意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深 ...
随机推荐
- MyBatis学习 之 二、SQL语句映射文件(2)增删改查、参数、缓存
目录(?)[-] 二SQL语句映射文件2增删改查参数缓存 select insert updatedelete sql parameters 基本类型参数 Java实体类型参数 Map参数 多参数的实 ...
- 保护眼睛,开启浏览器的夜间模式 顺便学下!important的作用
打开笔记本程序,复制以下代码 *{background-image: none !important; background: none !important; background:#333333 ...
- ASP.NET缓存策略经验谈
要提升ASP.NET应用程序的性能,最简单.最有效的方式就是使用内建的缓存引擎.虽然也能构建自己的缓存,但由于缓存引擎已提供了如此多的功能,所以完全不必如此麻烦.在很大程度上,ASP.NET开发者在W ...
- Fragment怎么实现TabHost
Fragment如何实现TabHost TabHost是一个过时的类,它的功能可以由Fragment来实现. FragmentTransaction对fragment进行添加,移除,替换,以及执行其 ...
- hdu4561 bjfu1270 最大子段积
就是最大子段和的变体.最大子段和只要一个数组,记录前i个里的最大子段和在f[i]里就行了,但是最大子段积因为有负乘负得正这一点,所以还需要把前i个里的最小子段积存起来.就可以了.直接上代码: /* * ...
- C# 中如何判断某个字符串是否为空的方法 分享了三个方法来判断字
1. 三种常用的字符串判空串方法:Length法:bool isEmpty = (str.Length == 0);Empty法:bool isEmpty = (str == String.Empty ...
- kendoui-在线文本编辑器
文本编辑器用过很多,fckeditor是我之前用的最多的,但是问题也有很多,诸如安全问题,浏览器兼容问题..所以最近也一直在找替代产品,正好在研究kendo,所以就尝试了下kendo提供的edit控件 ...
- django form关于clean及cleaned_data的说明 以及4种初始化
1.form类的运行顺序是init,clean,validte,save其中clean和validate会在form.is_valid()方法中被先后调用.(这里留有一个疑问,结构完全相同的两个f ...
- hadoop-1.1.2集群搭建
Hadoop安装分为三种不同模式: 本地模式:hadoop在运行时,不使用hdfs,而是使用linux操作系统的文件系统.(默认hadoop就是本地模式) 伪分布模式:在一个节点上运行hadoop(指 ...
- scanf,sscanf利用format跳过干扰的空格
scanf,sscanf利用format跳过干扰的空格 用了一点时间做读取配置部分的代码,希望一次记录上读取N个数据, 希望读取的格式就是一个IP地址加上端口号,希望把IP地址读取到4个短整数里面,端 ...