Laying Cables (单调栈)

本文介绍了一维国家的互联网部署难题,通过计算找出每个城市的父节点,即拥有更大人口且距离最近的上级城市。算法实例展示了如何确定城市间电缆布局,优化网络覆盖,提升国家通信效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 the i-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.

Examples
Input
4
1 1000
7 10
9 1
12 100
Output
-1 4 2 1
Input
3
1 100
2 1
3 10
Output
-1 1 1
Input
3
1 10
3 100
2 1
Output
2 -1 2

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
struct node {
    int x, sum, id;
} s[N];
int cmp(node a, node b) { return a.x < b.x; }
int n, ans[N];
node a[N];
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &s[i].x, &s[i].sum);
        s[i].id = i;
    }
    sort(s + 1, s + 1 + n, cmp);
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (cnt == 0)
            a[++cnt] = s[i];
        else {
            while (s[i].sum > a[cnt].sum && cnt >= 1) {
                if (cnt == 1)
                    ans[a[cnt].id] = s[i].id;
                else {
                    if (a[cnt].x - a[cnt - 1].x == s[i].x - a[cnt].x) {
                        if (a[cnt - 1].sum > s[i].sum)
                            ans[a[cnt].id] = a[cnt - 1].id;
                        else
                            ans[a[cnt].id] = s[i].id;
                    } else if (a[cnt].x - a[cnt - 1].x < s[i].x - a[cnt].x) {
                        ans[a[cnt].id] = a[cnt - 1].id;
                    } else
                        ans[a[cnt].id] = s[i].id;
                }
                cnt--;
            }
            a[++cnt] = s[i];
        }
    }
    for (int i = cnt; i >= 2; i--) {
        ans[a[i].id] = a[i - 1].id;
    }
    ans[a[1].id] = -1;
    for (int i = 1; i <= n; i++) {
        if (i == n)
            printf("%d\n", ans[i]);
        else
            printf("%d ", ans[i]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值