题目链接: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)的更多相关文章

  1. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  2. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  3. CodeForces–833B--The Bakery(线段树&&DP)

    B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  4. lightoj1085 线段树+dp

    //Accepted 7552 KB 844 ms //dp[i]=sum(dp[j])+1 j<i && a[j]<a[i] //可以用线段树求所用小于a[i]的dp[j ...

  5. HDU-3872 Dragon Ball 线段树+DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3872 题意:有n个龙珠按顺序放在一列,每个龙珠有一个type和一个权值,要求你把这n个龙珠分成k个段, ...

  6. HDU4521+线段树+dp

    题意:在一个序列中找出最长的某个序列.找出的序列满足题中的条件. 关键:对于 第 i 个位置上的数,要知道与之相隔至少d的位置上的数的大小.可以利用线段树进行统计,查询.更新的时候利用dp的思想. / ...

  7. Codeforces Round #343 (Div. 2) D - Babaei and Birthday Cake 线段树+DP

    题意:做蛋糕,给出N个半径,和高的圆柱,要求后面的体积比前面大的可以堆在前一个的上面,求最大的体积和. 思路:首先离散化蛋糕体积,以蛋糕数量建树建树,每个节点维护最大值,也就是假如节点i放在最上层情况 ...

  8. [Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】

    题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi ...

  9. Special Subsequence(离散化线段树+dp)

    Special Subsequence Time Limit: 5 Seconds      Memory Limit: 32768 KB There a sequence S with n inte ...

随机推荐

  1. jquery显示隐藏toggle

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. smarty变量调节器案例

    要求: 如下图,有内容的每一行,当鼠标放上去显示灰色区域,当鼠标离开灰色区域消失

  3. ettercap ARP dns 欺骗

    1.arp 这个简单,太熟了.略过1     2.dns   根据arp欺骗的步骤. 多了个etter.dns文件 找到它:locate etter.dns 进入后添加dns正向解析     启动,选 ...

  4. 【转】Asp.Net MVC3 简单入门详解过滤器Filter

    原文地址:http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组 ...

  5. 警告: [SetContextPropertiesRule]{Context} Setting property 'source' to 'org.eclipse.jst.jee.server:20160928' did not find a matching property

    控制台看到如下警告: 症状原因: 在eclipse配置好的tomcat服务器上双击,打开tomcat服务器的配置界面.按如下操作配置服务器:在Server Options勾上的选项,会在你部署web项 ...

  6. select,epool,pool解释

    内容主要来自搜狗实验室技术交流文档, 编写链接数巨大的高负载服务器程序时,经典的多线程模式和select模式都不再适合了.应该采用epool/kqueue/dev_pool来捕获IO事件. ----- ...

  7. 黄聪:wordpress如何获取当前分类页面的ID、名称、别名(slug)

    <? global $wp_query; $cat_ID = get_query_var('cat'); $category = get_category($cat_ID); echo $cat ...

  8. zookeeper进行leader选举

    一.如何进行leader选举 创建 /lj/producer和/lj/master/producer外层节点 创建临时顺序节点 判断自己是否是master节点(判断流程:遍历/lj/producer节 ...

  9. C# new 和 override.

    http://www.dotblogs.com.tw/skychang/archive/2012/05/10/72114.aspx?fid=60865

  10. maven命令行跳过test

    mvn跳过测试的两种方法: -DskipTests -Dmaven.test.skip=true