【BZOJ】【2500】幸福的道路
树形DP+单调队列优化DP
好题(也是神题……玛雅我实在是太弱了TAT,真是一个250)
完全是抄的zyf的……orz我还是退OI保平安吧
第一步对于每一天求出一个从第 i 个点出发走出去的最长链的长度,树形DP解决……
g[x][0]表示从x的子树中,x到叶子的最长链,g[x][1]表示次长链。(用儿子更新父亲)
f[x]表示从x向上走到某个父亲,再向下的最长链。(用父亲更新儿子)
这个DP是通过两次从根出发的dfs实现的。
那么我们现在就得到了a[i]=max(f[i],g[i][0])表示从 i 出发的最长链的长度。
第二步是要在a数组中求一段最长的区间满足极差小于等于m。
这个居然可以单调队列QAQ(当然啦……右端点为1~n时,左端点也是单调向右移动的!)
用两个队列分别维护最大值和最小值,将当前结点入队后,如果最大值-最小值(两个队列的队头)>m,则选一个较小的队头,以 i 为右节点的最长区间 的左端点,就是较小的队头表示的位置+1,(扔掉那个最小的以后剩下的就合法了啊)(才怪!如果不合法,继续扔,边扔边更新答案)
sigh……DP真是一种神奇的算法……我还是too young too naive
UPD:2015-04-24 11:14:03
其实第二步我以前做过的QAQ,早忘了而已……
- /**************************************************************
- Problem: 2500
- User: Tunix
- Language: C++
- Result: Accepted
- Time:2496 ms
- Memory:55960 kb
- ****************************************************************/
- //Huce #1 C
- #include<vector>
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<iostream>
- #include<algorithm>
- #define rep(i,n) for(int i=0;i<n;++i)
- #define F(i,j,n) for(int i=j;i<=n;++i)
- #define D(i,j,n) for(int i=j;i>=n;--i)
- #define pb push_back
- using namespace std;
- inline int getint(){
- int v=,sign=; char ch=getchar();
- while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
- while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
- return v*sign;
- }
- const int N=1e6+,INF=~0u>>;
- typedef long long LL;
- /******************tamplate*********************/
- int to[N],next[N],head[N],len[N],cnt;
- void add(int x,int y,int z){
- to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt; len[cnt]=z;
- }
- int n,m;
- LL f[N],g[N][],a[N];
- void down(int x){
- for(int i=head[x];i;i=next[i]){
- down(to[i]);
- if (g[to[i]][]+len[i]>g[x][]){
- g[x][]=g[x][];
- g[x][]=g[to[i]][]+len[i];
- }else g[x][]=max(g[x][],g[to[i]][]+len[i]);
- }
- }
- void up(int x){
- int y;
- for(int i=head[x];i;i=next[i]){
- f[y=to[i]]=f[x]+len[i];
- if (g[y][]+len[i]==g[x][]) f[y]=max(f[y],g[x][]+len[i]);
- else f[y]=max(f[y],g[x][]+len[i]);
- up(y);
- }
- }
- int Q1[N],Q2[N];
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("C.in","r",stdin);
- freopen("C.out","w",stdout);
- #endif
- n=getint(); m=getint();
- int x,y,z;
- F(i,,n){
- x=getint(); z=getint();
- add(x,i,z);
- }
- down(); up();
- F(i,,n) a[i]=max(f[i],g[i][]);
- LL ret=,ans=;int l1=,r1=-,l2=,r2=-;
- F(i,,n){
- while(l1<=r1 && a[i]<=a[Q1[r1]]) r1--;
- Q1[++r1]=i;
- while(l2<=r2 && a[i]>=a[Q2[r2]]) r2--;
- Q2[++r2]=i;
- while(a[Q2[l2]]-a[Q1[l1]]>m)
- ret=Q1[l1]<Q2[l2] ? Q1[l1++]+ : Q2[l2++]+;
- ans=max(ans,i-ret+);
- }
- printf("%lld\n",ans);
- return ;
- }
2500: 幸福的道路
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 153 Solved: 60
[Submit][Status][Discuss]
Description
顺序地从每个起点开始(第一天从起点一开始,第二天从起点二开始……).
而且他们给每条道路定上一个幸福的值.很显然他们每次出发都想走幸福值和最长的路线(即从起点到树上的某一点路径中最长的一条).
Input
Output
Sample Input
1 1
1 3
Sample Output
数据范围:
50%的数据N<=1000
80%的数据N<=100 000
100%的数据N<=1000 000
HINT
Source
【BZOJ】【2500】幸福的道路的更多相关文章
- [BZOJ 2500] 幸福的道路
照例先贴题面(汪汪汪) 2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 368 Solved: 145[Submit][Sta ...
- [BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案
考试的时候打了个树链剖分,而且还审错题了,以为是每天找所有点的最长路,原来是每天起点的树上最长路径再搞事情.. 先用dfs处理出来每个节点以他为根的子树的最长链和次长链.(后面会用到) 然后用类似dp ...
- ●BZOJ 2500 幸福的道路
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2500 题解: DFS,单调队列 首先有一个结论,距离树上某一个点最远的点一定是树的直径的一个 ...
- bzoj 2500 幸福的道路 树上直径+set
首先明确:树上任意一点的最长路径一定是直径的某一端点. 所以先找出直径,求出最长路径,然后再求波动值<=m的最长区间 #include<cstdio> #include<cst ...
- BZOJ 2500 幸福的道路(race) 树上直径+平衡树
structHeal { priority_queue<int> real; priority_queue<int> stack; void push(int x){ real ...
- BZOJ2500: 幸福的道路
题解: 一道不错的题目. 树DP可以求出从每个点出发的最长链,复杂度O(n) 然后就变成找一个数列里最长的连续区间使得最大值-最小值<=m了. 成了这题:http://www.cnblogs.c ...
- bzoj2500幸福的道路 树形dp+单调队列
2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 434 Solved: 170[Submit][Status][Discuss ...
- [Bzoj2500]幸福的道路(树上最远点)
2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 474 Solved: 194[Submit][Status][Discuss ...
- 【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法
[BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的 ...
随机推荐
- asp.net解析请求报文
NameValueCollection myHeader = new NameValueCollection(); int i; string strKey; string result; myHea ...
- 第二章 管理程序流(In .net4.5) 之 管理多线程
1. 概述 本章包括同步资源以及取消长时间任务相关的内容. 2. 主要内容 2.1 同步资源 ① lock关键字实现.会阻塞程序,有可能会导致死锁. ② volatile关键字可以禁用编译优化,用于避 ...
- python Django 学习笔记(四)—— 使用MySQL数据库
1,下载安装MySQLdb类库 http://www.djangoproject.com/r/python-mysql/ 2,修改settings.py 配置数据属性 DATABASES = { 'd ...
- C 简易基础开发框架 - simple c
引言 一个为 简单高效而生的 简易跨平台的 纯C开发框架. githup上源码 https://github.com/wangzhione/sconsole_project 请容我细说 s ...
- oracle 查询谁在用undo
SELECT TO_CHAR(s.sid)||','||TO_CHAR(s.serial#) sid_serial,NVL(s.username, 'None') orauser,s.program, ...
- chattr 与 lsattr 命令详解
PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,不过现在生产绝大部分跑的li ...
- oracle 各种问题排查
一.ORA-00257 ORA-00257归档日志写满,最简单方法.可以更改归档的大小. 二.job不自动运行解决方法 http://www.cnblogs.com/xbding/p/5861443. ...
- 有关GIT
今天上班,发现没什么事情. 就看了一些博客,发现有个不错的东西,分享一下. 参考:http://www.liaoxuefeng.com/wiki/0013739516305929606dd183612 ...
- android Init 相关分析
Init.c主要工作 1. 初始化属性(包括建立/dev./proc等目录.初始化属性.log.执行init.rc等初始化文件中的action等). 2. 解析配置文件的命令(主要是init.rc文件 ...
- JavaScript高级程序设计之函数性能
setTimeout 比 setInterval 性能更好 // 取代setInterval setTimeout(function self () { // code goes here setTi ...