zoukankan      html  css  js  c++  java
  • 1109: [POI2007]堆积木Klo

    1109: [POI2007]堆积木Klo

    https://lydsy.com/JudgeOnline/problem.php?id=1109

    分析:

      首先是dp,f[i]表示到第i个的最优值,f[i]=f[j]+1,(j<i,a[j]<a[i],j-a[j]<i-a[i]),三维偏序,可以cdq+线段树转移。实际上由a[j]<a[i]和j-a[j]<i-a[i]可以推出j<i所以二维偏序,直接LIS。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<cctype>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13  
    14 inline int read() {
    15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    17 }
    18  
    19 const int N = 1000005;
    20  
    21 struct Node{
    22     int x, c;
    23     bool operator < (const Node &A) const {
    24         return x == A.x ? c > A.c : x < A.x;
    25     } 
    26 }A[N]; 
    27 int f[N];
    28  
    29 int main() {
    30     int n = read(), cnt = 0;
    31     for (int i = 1; i <= n; ++i) {
    32         int x = read();
    33         if (i - x >= 0) 
    34         A[++cnt].x = x, A[cnt].c = i - x;
    35     }
    36     if (cnt == 0) {
    37         cout << 0; return 0;
    38     }
    39     int len = 1;
    40     sort(A + 1, A + cnt + 1);
    41     f[1] = A[1].c;
    42     for (int i = 2; i <= cnt; ++i) {
    43         if (A[i].x != A[i - 1].x && A[i].c >= f[len]) f[++len] = A[i].c;
    44         else {
    45             int p = upper_bound(f + 1, f + len + 1, A[i].c) - f;
    46             f[p] = A[i].c;
    47         }
    48     }
    49     cout << len;
    50     return 0;
    51 }
    52 
    LIS
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<cctype>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13  
    14 inline int read() {
    15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    17 }
    18  
    19 const int N = 1000005;
    20  
    21 struct Node{
    22     int id, x, c;
    23     bool operator < (const Node &A) const {
    24         return c == A.c ? x < A.x : c < A.c;
    25     } 
    26 }A[N], B[N]; 
    27 int f[N], mx;
    28  
    29 #define Root 1, mx, 1
    30 #define lson l, mid, rt << 1
    31 #define rson mid + 1, r, rt << 1 | 1
    32 struct SegmentTree{
    33     int mx[N << 2];
    34     SegmentTree() { for (int i = 0; i <= 4000000; ++i) mx[i] = -1e9; }
    35     void update(int l,int r,int rt,int p,int v) {
    36         if (l == r) { mx[rt] = v; return ; }
    37         int mid = (l + r) >> 1;
    38         if (p <= mid) update(lson, p, v);
    39         else update(rson, p, v);
    40         mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
    41     }
    42     int query(int l,int r,int rt,int p) {
    43         if (p < 1) return -1e9;
    44         if (r <= p) return mx[rt];
    45         int mid = (l + r) >> 1;
    46         if (p <= mid) return query(lson, p);
    47         else return max(mx[rt << 1], query(rson, p));
    48     }
    49 }T;
    50  
    51 void cdq(int l,int r) {
    52     if (l >= r) return ;
    53     int mid = (l + r) >> 1;
    54     cdq(l, mid);
    55     for (int i = mid + 1; i <= r; ++i) B[i] = A[i];
    56     sort(B + mid + 1, B + r + 1);
    57     for (int p = l, j = mid + 1; j <= r; ++j) {
    58         if (f[B[j].id] == -1e9) continue;
    59         while (p <= mid && A[p].c <= B[j].c) T.update(Root, A[p].x, f[A[p].id]), p ++;
    60         f[B[j].id] = max(f[B[j].id], T.query(Root, B[j].x - 1) + 1);    
    61     }
    62     for (int i = l; i <= mid; ++i) T.update(Root, A[i].x, 0); // B[i].x!!! 
    63     cdq(mid + 1, r);
    64     sort(A + l, A + r + 1);
    65 }
    66  
    67 int main() {
    68     int n = read();
    69     for (int i = 1; i <= n; ++i) {
    70         A[i].x = read(), A[i].id = i, A[i].c = i - A[i].x;
    71         if (A[i].x <= i) f[i] = 1;
    72         else f[i] = -1e9;
    73         mx = max(mx, A[i].x);
    74     }
    75     cdq(1, n);
    76     int ans = 0;
    77     for (int i = 1; i <= n; ++i) ans = max(ans, f[i]);
    78     cout << ans;
    79     return 0;
    80 }
    81 
    CDQ
  • 相关阅读:
    【hihocoder 1477】闰秒
    【codeforces 768F】Barrels and boxes
    【codeforces 767E】Change-free
    【codeforces 810A】Straight «A»
    【codeforces 810B】Summer sell-off
    【codeforces 810C】Do you want a date?
    【codeforces 757E】Bash Plays with Functions
    【codeforces 749D】Leaving Auction
    Java数据结构与算法(5)
    使用Xshell远程连接管理Linux实践
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10042689.html
Copyright © 2011-2022 走看看