小明系列问题——小明序列 【HDU

传送门

思路:我们需要求距离为d+1的LIS,我们可以用延迟更新方法,a[]为该点数值,f[]为以改点结尾的LIS长度。当inx - d - 1 > 0时,我们才更新这个点的信息,这样就解决了距离的问题。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <queue>
  5 
  6 using namespace std;
  7 
  8 #define ll long long
  9 #define pb push_back
 10 #define lson(rt) (rt << 1)
 11 #define rson(rt) (rt << 1 | 1)
 12 #define fi first
 13 #define se second
 14 
 15 const int N = 1e5 + 10;
 16 struct node
 17 {
 18     int rt, l, r, sum;
 19     int mid() { return(l + r) >> 1; }
 20     inline void init(int l1, int r1) { l = l1; r = r1; sum = 0; }
 21 }tree[N << 2];
 22 int a[N], f[N];
 23 
 24 void Build(int rt, int l, int r)
 25 {
 26     //printf("rt = %d  l = %d  r = %d
", rt, l, r);
 27     tree[rt].init(l, r);
 28     if(l == r) return ;
 29     Build(lson(rt), l, tree[rt].mid());
 30     Build(rson(rt), tree[rt].mid() + 1, r);
 31 }
 32 
 33 inline void Push_up(int rt)
 34 {
 35     tree[rt].sum = max(tree[lson(rt)].sum, tree[rson(rt)].sum);
 36 }
 37 
 38 void Update(int rt, int l, int r, int v, int sum)
 39 {
 40     //cout << "54 lines" << endl;
 41     //printf("rt = %d l = %d  r = %d v = %d
", rt, l , r, v);
 42     if(l == r) {
 43         tree[rt].sum = sum;
 44         return ;
 45     }
 46 
 47     if(tree[rt].mid() >= v) {
 48         Update(lson(rt), l, tree[rt].mid(), v, sum);
 49     } else {
 50         Update(rson(rt), tree[rt].mid() + 1, r, v, sum);
 51     }
 52 
 53     Push_up(rt);
 54 }
 55 
 56 int Search(int rt, int l, int r, int vl, int vr)
 57 {
 58     //cout << "34 lines" << endl;
 59     if(vl <= l && r <= vr) return tree[rt].sum;
 60 
 61     if(tree[rt].mid() >= vr) {
 62         return Search(lson(rt), l, tree[rt].mid(), vl, vr);
 63     } else if(tree[rt].mid() < vl) {
 64         return Search(rson(rt), tree[rt].mid() + 1, r, vl, vr);
 65     } else {
 66         return max(Search(lson(rt), l, tree[rt].mid(), vl, vr), 
 67             Search(rson(rt), tree[rt].mid() + 1, r, vl, vr));
 68     }
 69 }
 70 
 71 void solve()
 72 {
 73     int n, d;
 74     while(~scanf("%d%d", &n, &d)) {
 75 
 76         int Max_v = 0;
 77         for(int i = 1; i <= n; ++i) {
 78             scanf("%d", a + i);
 79             Max_v = max(Max_v, a[i]);
 80         }
 81         Build(1, 0, Max_v);
 82         //cout << "75 lines" << endl;
 83         //cout << "Max_v = " << Max_v << endl;
 84         for(int i = 0; i <= n; ++i) f[i] = 0;
 85         //for(int i = 0; i <= Max_v; ++i) printf("%d ", f[i]);
 86         //printf("
");
 87         
 88         int Max_len = 0;
 89         for(int i = 1; i <= n; ++i) {
 90             //cout << "i = " << i << endl;
 91             if(i - d > 1) Update(1, 0, Max_v, a[i - d - 1], f[i - d - 1]);
 92             if(a[i] > 0) {
 93                 f[i] = max(Search(1, 0, Max_v, 0, a[i] - 1) + 1, f[i]);
 94             } else f[i] = 1;
 95 
 96             Max_len = max(Max_len, f[i]);
 97         }
 98 
 99         //printf("Max_len = %d
", Max_len);
100         printf("%d
", Max_len);
101     }
102 }
103 
104 int main()
105 {
106     solve();
107 
108     return 0;
109 }
110 
111 
112 /*
113 16 3
114 1 1 1 1 2 2 2 2 3 3 3 6 4  6 6 7
115 
116 
117 17 3
118 1 1 1 1 2 2 2 2 3 3 3 6 6 6 4 4  7
119 
120 
121 17 3
122 1 1 1 1 2 2 2 2 3 3 3 5 4 4 4 4  7
123 
124 
125 10 2
126 1 1 1 2 2 6 4 6 6 7
127 
128 
129 10 3
130 1 1 1 2 2 6 4 6 6 7
131 
132 
133 7 1
134 1 1 2 6 4 4 7
135 
136 
137 4
138 5
139 5
140 3
141 4
142 4
143 
144 
145 */
原文地址:https://www.cnblogs.com/SSummerZzz/p/13971136.html