zoukankan      html  css  js  c++  java
  • 【CF】474E Pillars

    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+5;
     27 node_t nd[maxn<<2];
     28 __int64 h[maxn], hh[maxn];
     29 int fa[maxn], dp[maxn];
     30 
     31 void PushUp(int rt) {
     32     int lb = rt<<1;
     33     int rb = rt<<1|1;
     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 = -1;
     46     nd[rt].fa = 0;
     47     if (l == r)
     48         return ;
     49     int mid = (l+r)>>1;
     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)>>1;
     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)>>1;
     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=1; i<=n; ++i) {
    101         scanf("%I64d", &h[i]);
    102         hh[i] = h[i];
    103     }
    104     sort(h+1, h+1+n);
    105     m = unique(h+1, h+1+n) - (h+1);
    106     build(1, m, 1);
    107 
    108     for (i=n; i>0; --i) {
    109         dp[i] = 1;
    110         fa[i] = 0;
    111 
    112         tmp = hh[i] + d;
    113         if (tmp <= h[m]) {
    114             l = lower_bound(h+1, h+1+m, tmp) - h;
    115             node = query(l, m, 1, m, 1);
    116             if (node.mx+1 > dp[i]) {
    117                 dp[i] = node.mx + 1;
    118                 fa[i] = node.fa;
    119             }
    120         }
    121 
    122         tmp = hh[i] - d;
    123         if (tmp >= h[1]) {
    124             r = m+1;
    125             if (tmp < h[m])
    126                 r = upper_bound(h+1, h+1+m, tmp) - h;
    127             node = query(1, r-1, 1, m, 1);
    128             if (node.mx+1 > dp[i]) {
    129                 dp[i] = node.mx + 1;
    130                 fa[i] = node.fa;
    131             }
    132         }
    133 
    134         l = lower_bound(h+1, h+1+m, hh[i]) - h;
    135         update(l, i, 1, m, 1);
    136     }
    137 
    138     ans = dp[1];
    139     v = 1;
    140     for (i=2; i<=n; ++i) {
    141         if (dp[i] > ans) {
    142             ans = dp[i];
    143             v = i;
    144         }
    145     }
    146 
    147     printf("%d
    ", ans);
    148     printf("%d", v);
    149     while (fa[v]) {
    150         v = fa[v];
    151         printf(" %d", v);
    152     }
    153     putchar('
    ');
    154 
    155     #ifndef ONLINE_JUDGE
    156         printf("%d
    ", (int)clock());
    157     #endif
    158 
    159     return 0;
    160 }
  • 相关阅读:
    java09 队列Queue与Deque
    java08 Set
    java07 map
    SNMP学习
    NPM
    windows主机资源Snmp OIDs CPU, Memory, Disk等
    servlet3.0 @webfilter 过滤顺序
    snmp v3的安全配置 snmp认证与加密配置(53)
    CentOS 7.2 (mini) 里iptables防火墙怎么关闭?
    ORA-00845 MEMORY_TARGET not supported on this system 的解决
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4423223.html
Copyright © 2011-2022 走看看