题目链接:
http://codeforces.com/contest/522/problem/D
题意:
查询区间相同数的最小距离
题解:
用一个map记录前面的位置,然后离线搞一搞
单点更新,区间查询最小值
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 5e5+10; 17 18 struct node{ 19 int l,r,v; 20 }tree[maxn<<2]; 21 22 struct kk{ 23 int l,r,id; 24 bool operator<(const kk& rhs) const{ 25 return l > rhs.l; 26 } 27 }qu[maxn]; 28 29 int d[maxn],ans[maxn]; 30 map<int,int> mp; 31 32 void build(int rt,int l,int r){ 33 tree[rt].l = l, tree[rt].r = r; 34 tree[rt].v = INF; 35 36 if(l == r) return ; 37 int mid = (l+r)/2; 38 build(rt<<1,l,mid); 39 build(rt<<1|1,mid+1,r); 40 } 41 42 void pushup(int rt){ 43 tree[rt].v = min(tree[rt<<1].v, tree[rt<<1|1].v); 44 } 45 46 void update(int rt,int pos,int val){ 47 int L = tree[rt].l, R = tree[rt].r; 48 if(L == R){ 49 tree[rt].v = val; 50 return ; 51 } 52 53 int mid = (L+R) / 2; 54 if(pos <= mid) update(rt<<1,pos,val); 55 else update(rt<<1|1,pos,val); 56 pushup(rt); 57 } 58 59 int mi; 60 void query(int rt,int l,int r){ 61 int L = tree[rt].l, R = tree[rt].r; 62 if(l<=R && R<=r){ 63 mi = min(mi,tree[rt].v); 64 return ; 65 } 66 67 int mid = (L+R)/2; 68 if(l<=mid) query(rt<<1,l,r); 69 if(r>mid) query(rt<<1|1,l,r); 70 } 71 72 73 int main(){ 74 int n=read(), m=read(); 75 76 build(1,1,n); 77 for(int i=1; i<=n; i++) 78 d[i] = read(); 79 for(int i=1; i<=m; i++){ 80 qu[i].l = read(); 81 qu[i].r = read(); 82 qu[i].id = i; 83 } 84 sort(qu+1,qu+1+m); 85 86 int t = 1; 87 for(int i=n; i>=1; i--){ 88 if(mp[d[i]]){ // 如果已经出现过,就更新后面那个为 mp[d[i]]-i 就是隔多少个 89 update(1,mp[d[i]],mp[d[i]]-i); 90 } 91 mp[d[i]] = i; 92 while(qu[t].l == i){ // 每次查询保证前面的值不会影响到现在查询的区间,因为还没有更新。 93 mi = INF; 94 query(1,qu[t].l,qu[t].r); 95 if(mi == INF) 96 mi = -1; 97 ans[qu[t].id] = mi; 98 t++; 99 } 100 } 101 102 for(int i=1; i<=m; i++) 103 cout << ans[i] << endl; 104 105 return 0; 106 } 107 108 // http://codeforces.com/contest/522/problem/D