有N个值,其中他们为1~M,现在我们想知道满足1~i这些值都有的区间的最小长度是多长?保证存在这样的答案。
于是,我们可以考虑,从1开始,一直到M,我们想知道每个左端点包含1~i的最近右端点在哪里?然后答案就是min(R-L+1)了,然后就是怎么去维护这样一个东西。
首先,很容易发现,每个左端点最近的满足1~i的右端点,左端点从左到右,这样的右端点是单调不减的,于是,有这样的单调性了。
其次,我们可以看到如果值i+1有p1,p2,……,pk这几位置,那么可以发现,在[pj+1, p(j+1)]区间中,如果其中的左端点的最近右端点是小于等于p(j+1)的,那么就应当把小于等于p(j+1)的这段区间都更新为p(j+1)。
然后,答案就是min(R-L+1)了, 用一个线段树维护一下就可以啦。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 #include <limits> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <set> 12 #include <map> 13 #include <bitset> 14 #include <unordered_map> 15 #include <unordered_set> 16 #define lowbit(x) ( x&(-x) ) 17 #define pi 3.141592653589793 18 #define e 2.718281828459045 19 #define INF 0x3f3f3f3f 20 #define HalF (l + r)>>1 21 #define lsn rt<<1 22 #define rsn rt<<1|1 23 #define Lson lsn, l, mid 24 #define Rson rsn, mid+1, r 25 #define QL Lson, ql, qr 26 #define QR Rson, ql, qr 27 #define myself rt, l, r 28 #define pii pair<int, int> 29 #define MP(a, b) make_pair(a, b) 30 using namespace std; 31 typedef unsigned long long ull; 32 typedef unsigned int uit; 33 typedef long long ll; 34 const int maxN = 2e5 + 7; 35 int N, M; 36 namespace Segement 37 { 38 const int maxP = maxN << 2; 39 int val[maxP], lazy[maxP], ans[maxP]; 40 void build(int rt, int l, int r) 41 { 42 val[rt] = 0; lazy[rt] = 0; ans[rt] = INF; 43 if(l == r) return; 44 int mid = HalF; 45 build(Lson); build(Rson); 46 } 47 void pushdown(int rt, int l, int r) 48 { 49 if(lazy[rt]) 50 { 51 int mid = HalF; 52 lazy[lsn] = lazy[rt]; 53 lazy[rsn] = lazy[rt]; 54 val[lsn] = lazy[rt]; 55 val[rsn] = lazy[rt]; 56 ans[lsn] = lazy[rt] - mid + 1; 57 ans[rsn] = lazy[rt] - r + 1; 58 lazy[rt] = 0; 59 } 60 } 61 void pushup(int rt) 62 { 63 val[rt] = min(val[lsn], val[rsn]); 64 ans[rt] = min(ans[lsn], ans[rsn]); 65 } 66 void update(int rt, int l, int r, int ql, int qr, int x) 67 { 68 if(ql <= l && qr >= r) 69 { 70 val[rt] = x; 71 ans[rt] = x - r + 1; 72 lazy[rt] = x; 73 return; 74 } 75 pushdown(myself); 76 int mid = HalF; 77 if(qr <= mid) update(QL, x); 78 else if(ql > mid) update(QR, x); 79 else { update(QL, x); update(QR, x); } 80 pushup(rt); 81 } 82 int query(int rt, int l, int r, int qx) 83 { 84 if(l == r) 85 { 86 if(val[rt] > qx) return 0; 87 return l; 88 } 89 pushdown(myself); 90 int mid = HalF; 91 if(val[rsn] > qx) return query(Lson, qx); 92 else return query(Rson, qx); 93 } 94 } 95 using namespace Segement; 96 vector<int> vt[maxN]; 97 int main() 98 { 99 scanf("%d%d", &N, &M); 100 build(1, 1, N); 101 for(int i=1, x; i<=N; i++) 102 { 103 scanf("%d", &x); 104 vt[x].push_back(i); 105 } 106 for(int i=1, len, p; i<=M; i++) 107 { 108 len = (int)vt[i].size(); 109 p = query(1, 1, N, vt[i][0]); 110 if(p >= 1) update(1, 1, N, 1, min(p, vt[i][0]), vt[i][0]); 111 for(int j=1; j<len; j++) 112 { 113 p = query(1, 1, N, vt[i][j]); 114 if(p > vt[i][j - 1]) update(1, 1, N, vt[i][j - 1] + 1, min(p, vt[i][j]), vt[i][j]); 115 } 116 if(vt[i][len - 1] < N) update(1, 1, N, vt[i][len - 1] + 1, N, INF); 117 printf("%d%c", ans[1], i == M ? '\n' : ' '); 118 } 119 return 0; 120 } 121 /* 122 5 5 123 1 3 2 4 5 124 ans:1 3 3 4 5 125 */