H的范围是10^15,DP方程很容易想到。但是因为H的范围太大了,而n的范围还算可以接受。因此,对高度排序排重后。使用新的索引建立线段树,使用线段树查询当前高度区间内的最大值,以及该最大值的前趋索引。线段树中的结点索引一定满足i<j的条件,因为采用从n向1更新线段树结点。每次线段树查询操作就可以得到argmax(dp[L, R]),很据不等式很容易得到L和R的范围。

  1. /* 474E */
  2. #include <iostream>
  3. #include <string>
  4. #include <map>
  5. #include <queue>
  6. #include <set>
  7. #include <stack>
  8. #include <vector>
  9. #include <algorithm>
  10. #include <cstdio>
  11. #include <cmath>
  12. #include <ctime>
  13. #include <cstring>
  14. #include <climits>
  15. #include <cctype>
  16. using namespace std;
  17.  
  18. #define lson l, mid, rt<<1
  19. #define rson mid+1, r, rt<<1|1
  20.  
  21. typedef struct {
  22. __int64 mx;
  23. int fa;
  24. } node_t;
  25.  
  26. const int maxn = 1e5+;
  27. node_t nd[maxn<<];
  28. __int64 h[maxn], hh[maxn];
  29. int fa[maxn], dp[maxn];
  30.  
  31. void PushUp(int rt) {
  32. int lb = rt<<;
  33. int rb = rt<<|;
  34.  
  35. if (nd[lb].mx >= nd[rb].mx) {
  36. nd[rt].fa = nd[lb].fa;
  37. nd[rt].mx = nd[lb].mx;
  38. } else {
  39. nd[rt].fa = nd[rb].fa;
  40. nd[rt].mx = nd[rb].mx;
  41. }
  42. }
  43.  
  44. void build(int l, int r, int rt) {
  45. nd[rt].mx = -;
  46. nd[rt].fa = ;
  47. if (l == r)
  48. return ;
  49. int mid = (l+r)>>;
  50. build(lson);
  51. build(rson);
  52. }
  53.  
  54. void update(int x, int in, int l, int r, int rt) {
  55. if (l == r) {
  56. if (nd[rt].mx < dp[in]) {
  57. nd[rt].mx = dp[in];
  58. nd[rt].fa = in;
  59. }
  60. return ;
  61. }
  62. int mid = (l+r)>>;
  63. if (x <= mid)
  64. update(x, in, lson);
  65. else
  66. update(x, in, rson);
  67. PushUp(rt);
  68. }
  69.  
  70. node_t query(int L, int R, int l, int r, int rt) {
  71. node_t d;
  72. if (L<=l && R>=r)
  73. return nd[rt];
  74. int mid = (l+r)>>;
  75. if (R <= mid) {
  76. return query(L, R, lson);
  77. } else if (L > mid) {
  78. return query(L, R, rson);
  79. } else {
  80. node_t ln = query(L, R, lson);
  81. node_t rn = query(L, R, rson);
  82. return rn.mx>ln.mx ? rn:ln;
  83. }
  84. }
  85.  
  86. int main() {
  87. int i, j, k;
  88. int n, m, d;
  89. int ans, v;
  90. int l, r;
  91. node_t node;
  92. __int64 tmp;
  93.  
  94. #ifndef ONLINE_JUDGE
  95. freopen("data.in", "r", stdin);
  96. freopen("data.out", "w", stdout);
  97. #endif
  98.  
  99. scanf("%d %d", &n, &d);
  100. for (i=; i<=n; ++i) {
  101. scanf("%I64d", &h[i]);
  102. hh[i] = h[i];
  103. }
  104. sort(h+, h++n);
  105. m = unique(h+, h++n) - (h+);
  106. build(, m, );
  107.  
  108. for (i=n; i>; --i) {
  109. dp[i] = ;
  110. fa[i] = ;
  111.  
  112. tmp = hh[i] + d;
  113. if (tmp <= h[m]) {
  114. l = lower_bound(h+, h++m, tmp) - h;
  115. node = query(l, m, , m, );
  116. if (node.mx+ > dp[i]) {
  117. dp[i] = node.mx + ;
  118. fa[i] = node.fa;
  119. }
  120. }
  121.  
  122. tmp = hh[i] - d;
  123. if (tmp >= h[]) {
  124. r = m+;
  125. if (tmp < h[m])
  126. r = upper_bound(h+, h++m, tmp) - h;
  127. node = query(, r-, , m, );
  128. if (node.mx+ > dp[i]) {
  129. dp[i] = node.mx + ;
  130. fa[i] = node.fa;
  131. }
  132. }
  133.  
  134. l = lower_bound(h+, h++m, hh[i]) - h;
  135. update(l, i, , m, );
  136. }
  137.  
  138. ans = dp[];
  139. v = ;
  140. for (i=; i<=n; ++i) {
  141. if (dp[i] > ans) {
  142. ans = dp[i];
  143. v = i;
  144. }
  145. }
  146.  
  147. printf("%d\n", ans);
  148. printf("%d", v);
  149. while (fa[v]) {
  150. v = fa[v];
  151. printf(" %d", v);
  152. }
  153. putchar('\n');
  154.  
  155. #ifndef ONLINE_JUDGE
  156. printf("%d\n", (int)clock());
  157. #endif
  158.  
  159. return ;
  160. }

【CF】474E Pillars的更多相关文章

  1. 【CF】438E. The Child and Binary Tree

    http://codeforces.com/contest/438/problem/E 题意:询问每个点权值在 $c_1, c_2, ..., c_m$ 中,总权值和为 $s$ 的二叉树个数.请给出每 ...

  2. 【CF】148D Bag of mice

    http://codeforces.com/problemset/problem/148/D 题意:w个白b个黑,公主和龙轮流取,公主先取,等概率取到一个.当龙取完后,会等概率跳出一只.(0<= ...

  3. 【CF】328 D. Super M

    这种图论题已经变得简单了... /* D */ #include <iostream> #include <string> #include <map> #incl ...

  4. 【CF】323 Div2. D. Once Again...

    挺有意思的一道题目.考虑长度为n的数组,重复n次,可以得到n*n的最长上升子序列.同理,也可以得到n*n的最长下降子序列.因此,把t分成prefix(上升子序列) + cycle(one intege ...

  5. 【CF】7 Beta Round D. Palindrome Degree

    manacher+dp.其实理解manacher就可以解了,大水题,dp就是dp[i]=dp[i>>1]+1如何满足k-palindrome条件. /* 7D */ #include &l ...

  6. 【CF】86 B. Petr#

    误以为是求满足条件的substring总数(解法是KMP分别以Sbeg和Send作为模式串求解满足条件的position,然后O(n^2)或者O(nlgn)求解).后来发现是求set(all vali ...

  7. 【CF】121 Div.1 C. Fools and Roads

    题意是给定一棵树.同时,给定如下k个查询: 给出任意两点u,v,对u到v的路径所经过的边进行加计数. k个查询后,分别输出各边的计数之和. 思路利用LCA,对cnt[u]++, cnt[v]++,并对 ...

  8. 【CF】310 Div.1 C. Case of Chocolate

    线段树的简单题目,做一个离散化,O(lgn)可以找到id.RE了一晚上,额,后来找到了原因. /* 555C */ #include <iostream> #include <str ...

  9. 【CF】110 Div.1 B. Suspects

    这题目乍眼一看还以为是2-sat.其实很水的,O(n)就解了.枚举每个人,假设其作为凶手.观察是否满足条件.然后再对满足的数目分类讨论,进行求解. /* 156B */ #include <io ...

随机推荐

  1. 在ASP.NET中ShowModalDialog+ztree的使用

    .aspx: <script type="text/javascript"> function getReturnValue() { var strResult = w ...

  2. c#不重复的排序方法

    public int getRandom(int num) { Thread.Sleep(5); // Random ro = new Random(unchecked((int)DateTime.N ...

  3. C#/.net七牛云存储上传图片(文件)操作

    七牛云存储官方: C#SDK(http://developer.qiniu.com/docs/v6/sdk/csharp-sdk.html) 注册成为标准用户就可获得:10GB永久免费存储空间/ 每月 ...

  4. BI任务列表

    了解点击流系统和pv/uv的相关计算 关于pv的那些事!! ···············································2014-09-10 homework做了些什 ...

  5. CenOs安装中文输入法

    http://jingyan.baidu.com/album/d8072ac4434666ec95cefda1.html?picindex=2 查看链接

  6. Asp.net Mvc对比Php的4大误解

    一:asp.net技术已过时,Php技术更新 Asp.net mvc 5 发布于2014 夏天. 二:php开发者更多,所以更能得到帮助 2者对比犹如下图,会拿电锯的肯定多少会点锯子, 会用锯子的不一 ...

  7. android-satellite-menu

    使用过Path的人都应该知道,在Path主界面的左下方有一个非常有意思的菜单.菜单由一个主按钮组成,当用户点击该按钮时,就会有一连串的按钮弹出,而Satellite Menu正是该菜单的一个开源版本. ...

  8. CSS中:nth-child和JQuery:eq的区别

    $("li:nth-child(n)")选择器与$("li:eq(n)")选择器的不同之处在于:$("li:eq(n)")选择器只匹配一个元 ...

  9. ASP.NET中扩展FileUpload的上传文件的容量

    ASP.NET中扩展FileUpload只能上传小的文件,大小在4MB以内的.如果是上传大一点的图片类的可以在web.config里面扩展一下大小,代码如下 <system.web> &l ...

  10. js输出单一字符字串

    <!DOCTYPE HTML> <html> <body> <input type="text" id="str" & ...