Phone Network【2020ICPC·小米 网络选拔赛第一场 E】【线段树】

题目链接

  有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 ? '
' : ' ');
118     }
119     return 0;
120 }
121 /*
122 5 5
123 1 3 2 4 5
124 ans:1 3 3 4 5
125 */
原文地址:https://www.cnblogs.com/WuliWuliiii/p/13883177.html