zoukankan      html  css  js  c++  java
  • 最近等对 (unique、lower_bound、离散化的配合)

    我的第一篇用了unique、lower_bound、离散化的代码!✿✿ヽ(°▽°)ノ✿

    一篇写的超好的离散化+unique函数+lower_bound函数等等函数的集合

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

    题目:

    现在有一个序列 a1, a2, ..., an ,还有m个查询 lj, rj (1 ≤ lj ≤ rj ≤ n) 。对于每一个查询,请找出距离最近的两个元素 ax 和 ay (x ≠ y) ,并且满足以下条件:

    ·          lj ≤ x, y ≤ rj; 

    ·         ax = ay。 

    两个数字的距离是他们下标之差的绝对值 |x − y| 。

    Input

    单组测试数据。

    第一行有两个整数n, m ,表示序列的长度和查询的次数。

    第二行有n个整数a1,a2,...,an (-10^9≤ai≤10^9)。

    接下来有m行,每一行给出两个整数lj,rj (1≤lj≤rj≤n)表示一个查询。

    对于20%的数据,1≤n,m≤300
    对于50%的数据,1≤n,m≤3000
    对于100%的数据,1≤n,m≤100000
    Output
    对于每一个查询,输出最近的距离,如果没有相等的元素,输出-1。
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Sample Input

    5 3

    1 1 2 3 2

    1 5

    2 4

    3 5

    Sample Output

    1

    -1

    2

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

    配有qiao详细注释的代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=500005,inf=90000000;
    int n,m,x,y,cnt,minn[MAXN<<2];
    int next[MAXN],a[MAXN],s[MAXN],first[MAXN],ans[MAXN];
    struct node{
     int l,r,id;    
    }q[MAXN];                            //q[].id说明这是第id次询问 
    bool cmp(node a,node b){
        return a.r<b.r;
    }
    void build_tree(int l,int r,int o){  //一开始把整棵树的最小值都设得很大 
        if (l==r){
            minn[o]=inf; 
            return;
        }
        int mid=l+r>>1;
        build_tree(l,mid,o<<1);
        build_tree(mid+1,r,o<<1|1);
        minn[o]=inf;
    }
    void change(int l,int r,int o,int x,int k){ //求每两个等对之间的距离
        if (l==r){
            minn[o]=k;
            return;
        }
        int mid=l+r>>1;
        if (x<=mid) change(l,mid,o<<1,x,k);
        else change(mid+1,r,o<<1|1,x,k);
        minn[o]=min(minn[o<<1],minn[o<<1|1]); 
    }
    int query(int l,int r,int o,int x,int y){   //询问在这个区间的最小距离 
        if (x<=l&&r<=y) return minn[o];
        int mid=l+r>>1;
        int ans=inf;
        if (x<=mid) ans=min(ans,query(l,mid,o<<1,x,y));
        if (y>mid)  ans=min(ans,query(mid+1,r,o<<1|1,x,y));
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),s[i]=a[i];//s[]是a[]的副本 
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            q[i].l=x,q[i].r=y,q[i].id=i;        //q[i].id表示第i次查询,把询问信息记录下来 
        }
        sort(s+1,s+n+1);                        //使用unique函数前要先排序,不然unique没用 
        sort(q+1,q+m+1,cmp);                    //到时就可以从左到右找下去 
        cnt=unique(s+1,s+n+1)-s-1;              //cnt表示s数组去重后元素的个数 
        for(int i=1;i<=n;i++) {
          //lower-bound返回的是把a[i]插进s数组中的位置(保持s的顺序)(不会真插进去,只是返回它应在的位置) 
          a[i]=lower_bound(s+1,s+cnt+1,a[i])-s; //a[]被离散化,成为新数组 ,元素顺序不变 
          /*如:s[]:1 4 5 6
                原a[]:1 5 4 6 4 1 5
                现a[]:1 3 2 4 2 1 3 
          */
          next[i]=first[a[i]],first[a[i]]=i;    //first[a[i]]记录值为a[i]的位置,next[i]为上一个a[i]的位置 
        }//这里有点像邻接表存图
        build_tree(1,n,1);
        for(int i=1,j=1;i<=n&&j<=m;i++){
            if (next[i]!=0){                    //next[i]!=0说明前面还有a[i]这个元素出现 
                change(1,n,1,next[i],i-next[i]);//i-next[i]代表它与上一个相同值的距离 
            } 
            while (i==q[j].r&&j<=m){ 
                ans[q[j].id]=query(1,n,1,q[j].l,q[j].r);
                j++;                            //query()完后这个询问就解决完了,处理下一个 
            }
        }
        for(int i=1;i<=m;i++) {
            if(ans[i]<inf) printf("%d
    ",ans[i]);
            else printf("-1
    ");                //没改过就说明不存在 
        }
    } 
  • 相关阅读:
    javascript继承对象冒充
    javascript原型prototype(2)
    javascript继承call()和apply实现继承
    javascript继承原型链继承
    javascript原型prototype(3)
    没有宽高的情况下实现水平垂直居中
    TCP协议
    什么是模块化?模块化的好处是什么?
    数组中嵌套数组,转化为一个数组形式/二维数组转化为一维数组
    常见的请求头类型
  • 原文地址:https://www.cnblogs.com/lxy050129/p/10538247.html
Copyright © 2011-2022 走看看