[CF 474E] Pillars (线段树+dp)
题目链接:http://codeforces.com/contest/474/problem/F
意思是给你两个数n和d,下面给你n座山的高度。
一个人任意选择一座山作为起始点,向右跳,但是只能跳到高度差的绝对值大于等于d的山上。
问跳过的最长路径是什么。
设dp[h[i]]是跳到第i座山的最长路径长度。
那么dp[h[i]] = max( dp[h[j]] ) + 1 ( |h[i]-h[j]| >=d && i>j )
因为要查询区间最大值,所以考虑用线段树实现。
从左向右扫,线段树seg[i]维护的是走到高度为i的山走的最长路径
那么先找出 区间 [0,h[i]-d] 的最长路径,再找出区间 [h[i]+d,n]的最长路径
然后求出最大的加1,再放入线段树的h[i]位置中。
注意要维护路径 还有离散化
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; const int MAX_N = *1e5+;
LL h[MAX_N],b[MAX_N];
// 这里写的时候偷懒了,sum代表高度对应的最长路径,maxn代表当前高度对应的最近的下标
int sum[MAX_N<<], maxn[MAX_N<<],dp[MAX_N],qq[MAX_N],n,d;
int route[MAX_N]; void push_up(int idx){
sum[idx] = max(sum[idx<<],sum[idx<<|]);
if( sum[idx<<]>sum[idx<<|] ) maxn[idx] = maxn[idx<<];
else maxn[idx] = maxn[idx<<|];
} // 更新pos的山的路径长,并且下标置为i
void update(int pos,int x,int i,int idx,int l,int r){
if( l==r ){
sum[idx] = x;
maxn[idx] = i;
return;
}
int m = l+r>>;
if( pos<=m ) update(pos,x,i,idx<<,l,m);
else update(pos,x,i,idx<<|,m+,r);
push_up(idx);
} // 传入的i是要被修改的,返回路径最长的山的位置
int query(int L,int R,int &i,int idx,int l,int r){
if( R<l||r<L ) {
i = -;
return -;
}
if( L<=l&&R>=r ) {
i = maxn[idx];
return sum[idx];
}
int m = l+r>> , res = -;
if( L<=m ) {
int s;
int Q = query(L,R,s,idx<<,l,m);
if( Q>res ){
i = s;
res = Q;
}
}
if( R>m ){
int s;
int Q = query(L,R,s,idx<<|,m+,r);
if( Q>res ) {
res = Q;
i = s;
}
}
return res;
} int main(){
memset(maxn,-,sizeof(maxn)); int ptr = ;
scanf("%d%d",&n,&d);
for(int i=;i<n;i++){
scanf("%I64d",&h[i]);
b[ptr++] = h[i];
b[ptr++] = h[i]-1LL*d;
b[ptr++] = h[i]+1LL*d;
}
sort(b,b+ptr);
int ub = unique(b,b+ptr) - b; for(int i=;i<n;i++){
int r = lower_bound(b,b+ub,h[i]+d) - b;
int lmax = -;
int rs = query(r,ptr-,lmax,,,ptr-);
int rmax = -;
int l = lower_bound(b,b+ub,h[i]-d) - b;
int ls = query(,l,rmax,,,ptr-);
qq[i] = max(ls,rs);
int t = lower_bound(b,b+ub,h[i]) - b;
update(t,qq[i]+,i,,,ptr-);
if(ls>rs){
dp[i] = rmax;
} else {
dp[i] = lmax;
}
}
int idx = maxn[];
int ED = sum[];
printf("%d\n",ED);
int ptrr = ;
route[ptrr++] = idx;
while( route[ptrr-]> ){
int s = route[ptrr-];
route[ptrr] = dp[s];
ptrr++;
}
while( route[ptrr-]< ) ptrr--;
for(int i=ptrr-;i>=;i--){
printf("%d ",route[i]+);
}
return ;
}
代码
[CF 474E] Pillars (线段树+dp)的更多相关文章
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- CodeForces–833B--The Bakery(线段树&&DP)
B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...
- lightoj1085 线段树+dp
//Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...
- HDU-3872 Dragon Ball 线段树+DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872 题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段, ...
- HDU4521+线段树+dp
题意:在一个序列中找出最长的某个序列.找出的序列满足题中的条件. 关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小.可以利用线段树进行统计,查询.更新的时候利用dp的思想. / ...
- Codeforces Round #343 (Div. 2) D - Babaei and Birthday Cake 线段树+DP
题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...
- [Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】
题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi ...
- Special Subsequence(离散化线段树+dp)
Special Subsequence Time Limit: 5 Seconds Memory Limit: 32768 KB There a sequence S with n inte ...
随机推荐
- jmeter使用IP欺骗压力测试
最近在使用jmeter进行压力测试时需要使用类似于loadrunner的IP欺骗功能,经问津度娘无果后决定再次耐心研究jmeter官方文 档,终于发现在jmeter2.5以上的版本有此功能的实现,由于 ...
- 修改mysql root 密码
C:\Program Files\MySQL\MySQL Server 5.6\bin mysqld --skip-grant-tables 开启一新窗口:然后输入mysql -uroot -p up ...
- 服饰行业淘宝商城店铺首页设计报告-转载自http://bbs.paidai.com/topic/88363
店铺的设计 和 美工是2个完全不同的工作. 很多中小卖家,往往会模糊他们之间的差别. 好比要建造一座金茂大厦,先要有建筑设计师设计图纸,明确好建造的楼层数,具体框架结构,所用材料等等. 然后建筑施工队 ...
- centos curl版本nss改成openssl
在centos 6.2的系统里面的curl支持的https是nss版本的,而不是openssl的,所以在php使用curl访问https的时候会报Unable to load client key - ...
- 【linux】which和whereis
which和whereis都是查询命令的指令.区别的是: which能查询到命令所在位置: [root@andon tmp]# which ls alias ls='ls --color=auto' ...
- HackerRank "Lucky Numbers"
Great learning for me:https://www.hackerrank.com/rest/contests/master/challenges/lucky-numbers/hacke ...
- Configure Puppet Master with Passenger and Apache on Centos
What is Passenger? Passenger (AKA mod_rails or mod_rack) is an Apache 2.x module which lets you run ...
- Mysql游标的简明写法
-- cursor 游标/*declare 声明; declare 游标名 cursor for select_statement;open 找开; open 游标名fetch 取值; fetch 游 ...
- C#学习笔记二: C#类型详解
前言 这次分享的主要内容有五个, 分别是值类型和引用类型, 装箱与拆箱,常量与变量,运算符重载,static字段和static构造函数. 后期的分享会针对于C#2.0 3.0 4.0 等新特性进行. ...
- BestCoder Round #86 部分题解
Price List 题意: 有n件商品,每天只能买一件,并且会记录账本,问有多少次一定记多了? 题解: 就是求和,最后如果大于和就输出1,否则0. 代码: #include <bits/std ...