Closest Equals(2000 segment tree + sort)

 

 

  1 /**\
  2 https://codeforces.com/contest/522/problem/D
  3 离线查询, 按照右端点小的排前面,
  4 使用p[x] 记录a[x]出现相同值的前一个位置, p[x]当作线段树的坐标, x - p[x]为值,
  5 olgN进行加点, 然后查询
  6 \**/
  7 #include <bits/stdc++.h>
  8 using namespace std;
  9 #define fi first
 10 #define se second
 11 
 12 #define go continue
 13 #define int long long
 14 #define PII pair<int, int>
 15 #define sf(x) scanf("%lld",&x)
 16 #define ytz int _; sf(_); while(_--)
 17 
 18 #define RE(i, a) for(int i = 1; i <= a; ++i)
 19 #define debug(a) cout << #a << " = " << a <<endl;
 20 
 21 const int N = 5e5 + 10;
 22 const int inf = 0x3f3f3f3f;
 23 
 24 int n, m;
 25 int ok[N], p[N];
 26 unordered_map<int, int> vis;
 27 
 28 struct Query
 29 {
 30     int l, r, id;
 31     bool operator < (const Query& t) const
 32     {
 33         return r < t.r;
 34     }
 35 } q[N];
 36 
 37 struct node
 38 {
 39     int l, r, mn;
 40 } t[N << 2];
 41 int mp[N]; //快速单点修改, 记录底层叶子节点的root值
 42 
 43 inline void build(int root, int l, int r)
 44 {
 45     t[root].l = l, t[root].r = r;
 46     t[root].mn = inf;
 47     if(l == r)
 48     {
 49         mp[l] = root;
 50         return;
 51     }
 52     int ch = root << 1;
 53     int mid = (l + r) >> 1;
 54     build(ch, l, mid);
 55     build(ch + 1, mid + 1, r);
 56 }
 57 
 58 inline void update(int x, int y)
 59 {
 60     x = mp[x];
 61     t[x].mn = (t[x].mn, y);
 62     while(x >>= 1)
 63     {
 64         int ch = x << 1;
 65         t[x].mn = min(t[ch].mn, t[ch + 1].mn);
 66     }
 67 }
 68 
 69 inline int query(int root, int l, int r)
 70 {
 71     if(t[root].l >= l && t[root].r <= r)
 72     {
 73         return t[root].mn;
 74     }
 75     int ch = root << 1;
 76     int mid = (t[root].l + t[root]. r) >> 1;
 77     if(r <= mid) return query(ch, l, r);
 78     else if(l > mid) query(ch + 1, l, r);
 79     else return min(query(ch, l, mid), query(ch + 1, mid + 1, r));
 80 }
 81 
 82 signed main()
 83 {
 84     sf(n), sf(m);
 85     build(1, 1, n);
 86 
 87     int x;
 88     RE(i, n)
 89     {
 90         sf(x);
 91 
 92         if(vis[x]) p[i] = vis[x], vis[x] = i;
 93         else vis[x] = i, p[i] = 0;
 94     }
 95     RE(i, m)
 96     {
 97         sf(q[i].l), sf(q[i].r);
 98         q[i].id = i;
 99     }
100     sort(q + 1, q + 1 + m);
101     int id = 1;
102     RE(i, m)
103     {
104         while(id <= q[i].r)
105         {
106             if(p[id]) update(p[id], id - p[id]);
107             id++;
108         }
109         int tmp  = query(1, q[i].l, id - 1);
110         if(tmp >= inf) ok[q[i].id] = -1;
111         else ok[q[i].id] = tmp;
112     }
113     RE(i, m) printf("%lld\n", ok[i]);
114     return 0;
115 }

 

posted @ 2022-03-10 10:32  std&ice  阅读(56)  评论(0编辑  收藏  举报