码迷,mamicode.com
首页 > 其他好文 > 详细

Gym 100971D Laying Cables

时间:2016-08-28 20:50:55      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

要求找出每个a[i],找到离他最近而且权值比它大的点,若距离相同,输出权利最大的那个

我的做法有点复杂,时间也要500+ms,因为只要时间花在了map上。

具体思路是模拟一颗树的建立过程,对于权值最大的那个,必须是-1,次大的那个,必须是pos_peo[mx];就是最大人口的节点id、

然后维护一个单调的序列,记录当前有多少个位置加入了树。用个set保证单调性。小到大

把结构体按人口排序大到小,枚举没个城市,这样保证加入后,后面加入的直接找位置最短即可,人口最对的bigger than now的。

二分一个位置,> now.pos的,枚举它左右,选择即可。注意就是当距离相同的时候,还要再判断一次。

技术分享
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 200000 + 50;
map<int,int>pos_peo;
map<int,int>pos_pos;
struct data {
    int pos,peo;
} a[maxn],b[maxn];
int ans[maxn];

struct cmp1 {
    bool operator()(int a,int b) {
        return a < b; //
    }
};
bool cmp2 (data a,data b)
{
    return a.peo > b.peo;
}
set<int,cmp1>SS;
void work ()
{
    int n;
    scanf ("%d",&n);
    int mx = -inf;
    for (int i=1; i<=n; ++i) {
        scanf ("%d%d",&a[i].pos,&a[i].peo);
        b[i].pos=a[i].pos;
        b[i].peo=a[i].peo;
        pos_peo[a[i].peo] = i; //id
        pos_pos[a[i].pos] = i;
        mx = max(mx,a[i].peo);
    }
    if (n==1) {
        printf ("-1\n");
        return ;
    }
    ans[pos_peo[mx]] = -1;
    int sec = -inf;
    for (int i=1; i<=n; ++i) {
        if (sec < a[i].peo && a[i].peo != mx)
            sec = a[i].peo;
    }
    ans[pos_peo[sec]] = pos_peo[mx];

    SS.insert(a[pos_peo[mx]].pos);
    SS.insert(a[pos_peo[sec]].pos);

    sort (a+1,a+1+n,cmp2); // peo up to low

    set<int>::iterator it;
    for (int i=3; i<=n; ++i) {
        int val = a[i].pos;
        int ppeo = a[i].peo;
        it = SS.lower_bound(val);
        int t1 = inf,t2 = inf;
        if (it == SS.begin()) { //在开头
            ans[pos_peo[a[i].peo]] = pos_pos[*it];
        } else if (it == SS.end()) { //在末尾
            it --;
            ans[pos_peo[a[i].peo]] = pos_pos[*it];
        } else {
            int tt1 = *it;
            t1 = abs(val - (*it));
            it--;
            int tt2 = *it;
            t2 = abs(val - (*it));
            if (t1 < t2) {
                ans[pos_peo[a[i].peo]] = pos_pos[tt1];
            } else if (t1 > t2) {
                ans[pos_peo[a[i].peo]] = pos_pos[tt2];
            } else { //xiangdeng
                int id2 = pos_pos[tt1];
                int id1 = pos_pos[tt2];
                int cut2 = abs(b[id2].peo - ppeo);
                int cut1 = abs(b[id1].peo - ppeo);
                if (cut2 > cut1) {
                    ans[pos_peo[a[i].peo]] = pos_pos[tt1];
                } else {
                    ans[pos_peo[a[i].peo]] = pos_pos[tt2];
                }
            }
        }
        SS.insert(a[i].pos);
    }
    for (int i=1; i<=n; ++i) {
        printf ("%d ",ans[i]);
    }
    printf ("\n");
}
int main()
{
#ifdef LOCAL
    freopen("data.txt","r",stdin);
#endif
    work ();
    return 0;
}
View Code

 

Gym 100971D Laying Cables

标签:

原文地址:http://www.cnblogs.com/liuweimingcprogram/p/5815899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!