zoukankan      html  css  js  c++  java
  • Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D

    题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查询,输出在这个区间内的两个相等的数的最短距离,如果没有相等的则输出-1.

      线段树+扫描线,线段树维护的值是区间的最小值,从后往前扫,然后每次要做的事有两个:

    1.判断当前这个位置 i 的数刚刚是不是出现过,假设刚刚出现的位置是 l ,如果出现过,则在线段树中把l这个位置的值更新为 l - i,同时更新包含这个点的区间的最小值.

    2.判断有没有以当前这个位置为左端点的查询区间,如果有,就在线段树中查找这个区间里面的最小值.

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<map>
      6 #include<list>
      7 using namespace std;
      8 const int maxn = 500100,INF = 0x7fffff;
      9 map<int,int> mp;
     10 
     11 int n,m,A[maxn];
     12 struct node
     13 {
     14     int d,l,r;
     15 }tree[4*maxn];
     16 struct Node
     17 {
     18     int flag,ans;
     19     int l,r;
     20 }Q[maxn];
     21 bool cmp(Node a,Node b)
     22 {
     23     return a.l >= b.l;
     24 }
     25 void maketree(node *tree,int p)
     26 {
     27     if(tree[p].l == tree[p].r)
     28     {
     29         tree[p].d = INF;
     30         return ;
     31     }
     32     int mid = (tree[p].l + tree[p].r) / 2;
     33     tree[2*p].l = tree[p].l;
     34     tree[2*p].r = mid;
     35     tree[2*p+1].l = mid + 1;
     36     tree[2*p+1].r = tree[p].r;
     37     tree[2*p].d = tree[2*p+1].d = INF;
     38     maketree(tree,2*p);
     39     maketree(tree,2*p+1);
     40 }
     41 void update(node *tree,int p,int loc,int d)
     42 {
     43     if(tree[p].l == tree[p].r)
     44     {
     45         tree[p].d = min(tree[p].d,d);
     46         return ;
     47     }
     48     int mid = (tree[p].l + tree[p].r) / 2;
     49     if(loc <= mid)
     50         update(tree,2*p,loc,d);
     51     else update(tree,2*p+1,loc,d);
     52     tree[p].d  = min(tree[p].d,d);
     53 }
     54 int data_sear;
     55 void search(node *tree,int p,int l,int r)
     56 {
     57     if(tree[p].l == l && tree[p].r == r)
     58     {
     59         data_sear = min(data_sear,tree[p].d);
     60         return ;
     61     }
     62     int mid = (tree[p].l + tree[p].r) / 2;
     63     if(r <= mid) search(tree,2*p,l,r);
     64     else if(l <= mid && r > mid)
     65     {
     66         search(tree,2*p,l,mid);
     67         search(tree,2*p+1,mid+1,r);
     68     }
     69     else if(l > mid) search(tree,2*p+1,l,r);
     70 }
     71 
     72 bool cmp2(Node a,Node b)
     73 {
     74     return a.flag < b.flag;
     75 }
     76 int main()
     77 {
     78     while(scanf("%d%d",&n,&m)!=EOF)
     79     {
     80         for(int i = 1;i <= n;++i)
     81             scanf("%d",&A[i]);
     82         for(int i = 0;i < m;++i)
     83         {
     84             scanf("%d%d",&Q[i].l,&Q[i].r);
     85             Q[i].flag = i;
     86             Q[i].ans = INF;
     87         }
     88         sort(Q,Q+m,cmp);     //按照左端点排好序,方便下面二分查找
     89         tree[1].l = 1;
     90         tree[1].r = n;
     91         tree[1].d = INF;
     92         maketree(tree,1);   //构建好线段树
     93         mp.clear();
     94         int f = 0;   //指向当前的查询
     95         for(int i = n;i >= 1;--i)
     96         {
     97             if(mp[A[i]] != 0)
     98             update(tree,1,mp[A[i]],mp[A[i]]-i);   //更新线段树
     99             mp[A[i]] = i;
    100             while(f < m && Q[f].l == i)
    101             {
    102                 data_sear = INF;
    103                 search(tree,1,Q[f].l,Q[f].r);   //查询这个区间内的最小值
    104                 Q[f].ans = (data_sear <= n? data_sear:-1);
    105                 f++;
    106             }
    107         }
    108         sort(Q,Q+m,cmp2);
    109         for(int i = 0;i < m;++i)
    110             printf("%d
    ",Q[i].ans);
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    浮点数转换成二进制的方法
    复杂的函数声明
    任务栏上最小化程序后,应用程序仍然处于激活状态
    处理多屏
    托盘在XP下不能显示tooltip,在Vista和Windows7下正常
    第一次WM_PAINT事件执行前显示白色框 的解决办法
    IPv6地址在URL上的格式
    19 层模型中的固定定位
    18css中的相对定位
    17css中的浮动模型
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4333476.html
Copyright © 2011-2022 走看看