zoukankan      html  css  js  c++  java
  • Gym 100971D Laying Cables 单调栈

    Description

     

    One-dimensional country has n cities, the i-th of which is located at the point xi and has population pi, and all xi, as well as all pi, are distinct. When one-dimensional country got the Internet, it was decided to place the main server in the largest city, and to connect any other city j to the city k that has bigger population than j and is the closest to it (if there are many such cities, the largest one should be chosen). City k is called a parent of city j in this case.

    Unfortunately, the Ministry of Communications got stuck in determining from where and to where the Internet cables should be laid, and the population of the country is suffering. So you should solve the problem. For every city, find its parent city.

    Input

     

    The first line contains a single integer n(1 ≤ n ≤ 200000) — the number of cities.

    Each of the next n lines contains two space-separated integers xi and pi(1 ≤ xi,  pi ≤ 109) — the coordinate and the population of thei-th city.

    Output

     

    Output n space-separated integers. The i-th number should be the parent of the i-th city, or  - 1, if the i-th city doesn't have a parent. The cities are numbered from 1 by their order in the input.

    Sample Input

    4
    1 1000
    7 10
    9 1
    12 100
    -1 4 2 1
     
    题意:
       给你n个点在x轴上的位置x和权值pos 
      对于一个第i点 他的父亲定义为 和他最近并且 权值大于p[i]的 为点
      输出每个点父亲,没有满足的作其父亲的点输出-1;
    题解:
      单调栈预处理出第i个点左边的父亲,和右边的父亲,去最近,权值最大的一个
      作一遍RMQ,二分左边的父亲是谁,最优解是最靠近的点
     
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6+20, M = 1e6+10, mod = 1e9+7, inf = 2e9;
    typedef long long ll;
    
    int n,ans[N];
    struct ss{long long x,p;int id;}a[N],lefts[N],rights[N];
    vector<ss> G;
    bool cmp(ss s1,ss s2) {return s1.x<s2.x;}
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%I64d%I64d",&a[i].x,&a[i].p),a[i].id = i;
        sort(a+1,a+n+1,cmp);
        a[0].x=-inf, a[0].p = inf; a[0].id = -1;
        G.push_back(a[0]);
        for(int i=1;i<=n;i++) {
            while(G.back().p<=a[i].p) G.pop_back();
            lefts[i]=G.back();
            G.push_back(a[i]);
        }
        G.clear();
        a[n+1] = (ss) {inf,inf,-1};
        G.push_back(a[n+1]);
        for(int i=n;i>=1;i--) {
            while(G.back().p<=a[i].p) G.pop_back();
            rights[i]=G.back();
            G.push_back(a[i]);
        }
    
        for(int i=1;i<=n;i++) {
            if(abs(lefts[i].x-a[i].x)==abs(rights[i].x-a[i].x)) {
                if(lefts[i].p>rights[i].p) ans[a[i].id] = lefts[i].id;
                else ans[a[i].id] = rights[i].id;
            }
            else if(abs(lefts[i].x-a[i].x)<abs(rights[i].x-a[i].x)) {
               ans[a[i].id] = lefts[i].id;
            }
            else ans[a[i].id] = rights[i].id;
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        printf("
    ");
    }
    单调栈
     
     
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5+20, M = 1e6+10, mod = 1e9+7, inf = 2e9;
    typedef long long ll;
    
    int n;
    ll dp[N][19];
    int ans[N];
    
    struct ss{long long  x,p;int id;}a[N],lefts[N],rights[N];
    
    bool cmp(ss s1,ss s2) {return s1.x<s2.x;}
    ll cal(int l,int r)
    {
        if(l==r) return a[l].p;
        int k = (int) (log((double) r-l+1) / log(2.0));
        return max(dp[l][k], dp[r - (1<<k) + 1][k]);
    }
    int main() {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%I64d%I64d",&a[i].x,&a[i].p), a[i].id=i;
        sort(a+1,a+n+1,cmp);
        a[0] = (ss) {-inf,inf,-1};
        a[n+1] = (ss){inf,inf,-1};
          for(int i=0;i<=n+1;i++) dp[i][0] = a[i].p;
        for(int j=1;(1<<j)<=n+1;j++) {
            for(int i=0;i + (1<<j) - 1 <= n+1; i++) {
                if(dp[i][j-1] > dp[i+(1<<(j-1))][j-1])
                    dp[i][j] =  dp[i][j-1];
                else {
                     dp[i][j] =  dp[i+(1<<(j-1))][j-1];
                }
            }
        }
        //cout<<cal(0,1)<<endl;
        for(int i=1;i<=n;i++) {
            int l = 0, r = i-1,A=0;
            while(l<=r) {
                int mid = (l+r) >> 1;
                if(cal(mid,i-1)> a[i].p) l = mid+1,A=mid;
                else r = mid-1;
            }
            lefts[i] = a[A];
           // cout<<A<<" ";
            l = i+1, r = n+1;A = n+1;
            while(l<=r) {
                int mid = (l+r) >> 1;
                if(cal(i+1,mid)> a[i].p) r=mid-1,A = mid;
                else l = mid+1;
            }
            rights[i] = a[A];
        //    cout<<A<<endl;
        }
    
        for(int i=1;i<=n;i++) {
            if(abs(lefts[i].x-a[i].x)==abs(rights[i].x-a[i].x)) {
                if(lefts[i].p>rights[i].p) ans[a[i].id] = lefts[i].id;
                else ans[a[i].id] = rights[i].id;
            }
            else if(abs(lefts[i].x-a[i].x)<abs(rights[i].x-a[i].x)) {
               ans[a[i].id] = lefts[i].id;
            }
            else ans[a[i].id] = rights[i].id;
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        printf("
    ");
    
    }
    RMQ+二分
  • 相关阅读:
    OpenGL ES应用开发实践指南:iOS卷
    WCF(1)----服务创建
    算法设计--电路布线问题(分支限界法求解)
    Oracle 删除用户和表空间
    从最简单的源代码开始,切勿眼高手低---(第一波)
    pinyin4j的使用
    ios学习:AVAudioPlayer播放音乐文件及读取ipod库中的音乐文件
    ArcGIS多面体(multipatch)解析——引
    [珠玑之椟]位向量/位图的定义和应用
    搭建自己的XenServer+CloudStack云平台,提供IaaS服务(一)环境搭建
  • 原文地址:https://www.cnblogs.com/zxhl/p/5664011.html
Copyright © 2011-2022 走看看