Codeforces VK Cup 2015 - Qualification Round 1 D. Closest Equals 离线线段树 求区间相同数的最小距离

题目链接:

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

 

posted @ 2017-03-11 21:39  _yxg123  阅读(134)  评论(0编辑  收藏  举报