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 }