Code Forces Gym 100971D Laying Cables(单调栈)

D - Laying Cables

Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

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

Input

41 10007 109 112 100

Output

-1 4 2 1

Input

31 1002 13 10

Output

-1 1 1

Input

31 103 1002 1

Output

2 -1 2

题意:给定一维数轴上的N个点和对应的权值,同时定义一个点的父亲为:离它最近且权值比它大的点下标,如果距离相同则选择权值较大的,如果没有则为-1,求出所有点的父亲?

思路1:单调栈预处理出左边和右边第一个比它大的元素的下标即可。       单调栈的作用:求出某个数的左边或右边第一个比它大或比它小的元素,复杂度O(n)。       单调递增栈:元素从栈底到栈顶严格单调递增。       单调递减栈:元素从栈底到栈顶严格单调递减。

代码1:

 1 #include <iostream>
 2 #include <queue>
 3 #include <stack>
 4 #include <cstdio>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <bitset>
 9 #include <algorithm>
10 #include <cmath>
11 #include <cstring>
12 #include <cstdlib>
13 #include <string>
14 #include <sstream>
15 #define x first
16 #define y second
17 #define pb push_back
18 #define mp make_pair
19 #define lson l,m,rt*2
20 #define rson m+1,r,rt*2+1
21 #define mt(A,B) memset(A,B,sizeof(A))
22 #define mod 1000000007
23 using namespace std;
24 typedef long long LL;
25 const int N=200000+10;
26 const LL INF=0x3f3f3f3f3f3f3f3fLL;
27 LL val[N],id[N],x[N],ans[N],S[N],L[N],R[N];//S[N]表示单调栈
28 bool cmp(LL a,LL b)
29 {
30     return x[a]<x[b];
31 }
32 int main()
33 {
34 #ifdef Local
35     freopen("data.txt","r",stdin);
36 #endif
37     ios::sync_with_stdio(0);
38     LL i,j,k,n;
39     cin>>n;
40     for(i=1;i<=n;i++)
41     {
42         cin>>x[i]>>val[i];//x[i]表示在数轴上的位置,val[i]表示该点的价值
43         id[i]=i;
44     }
45     sort(id+1,id+1+n,cmp);//按在数轴上的位置从小到大排序
46     k=0;S[k++]=0;val[0]=2e9;//先把INF压入栈底
47     for(i=1;i<=n;i++)
48     {
49         while(val[S[k-1]]<=val[id[i]])k--;//如果当前的val比栈顶的大,就把栈顶的元素弹出来
50         L[id[i]]=S[k-1];//找到了左边第一个比他大的数的下标
51         S[k++]=id[i];//把当前的下标压入栈
52     }
53     k=n+1;S[k--]=n+1;val[n+1]=2e9;
54     for(i=n;i>=1;i--)//同理
55     {
56         while(val[S[k+1]]<=val[id[i]])k++;
57         R[id[i]]=S[k+1];
58         S[k--]=id[i];
59     }
60     for(i=1;i<=n;i++)
61     {
62         if(L[i]==0&&R[i]==n+1)ans[i]=-1;
63         else if(L[i]==0)ans[i]=R[i];
64         else if(R[i]==n+1)ans[i]=L[i];
65         else
66         {
67             if(abs(x[L[i]]-x[i])<abs(x[R[i]]-x[i]))ans[i]=L[i];
68             else if(abs(x[L[i]]-x[i])>abs(x[R[i]]-x[i]))ans[i]=R[i];
69             else
70             {
71                 if(val[L[i]]<val[R[i]])ans[i]=R[i];
72                 else if(val[L[i]]>val[R[i]])ans[i]=L[i];
73             }
74         }
75     }
76     for(i=1;i<=n;i++)
77     {
78         if(i==n)cout<<ans[i]<<endl;
79         else cout<<ans[i]<<" ";
80     }
81 }


思路2:先按数轴上的位置排序,RMQ预处理区间的最大值,再往左往右二分。训练的时候并不会单调栈,所以只能用RMQ二分瞎几把乱搞。

代码2:

  1 #include <iostream>
  2 #include <queue>
  3 #include <stack>
  4 #include <cstdio>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <bitset>
  9 #include <algorithm>
 10 #include <cmath>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <string>
 14 #include <sstream>
 15 #define lson l,m,rt*2
 16 #define rson m+1,r,rt*2+1
 17 #define mod 1000000007
 18 #define mt(A) memset(A,0,sizeof(A))
 19 using namespace std;
 20 typedef long long LL;
 21 const int N=200000+10;
 22 const LL INF=0x3f3f3f3f3f3f3f3fLL;
 23 LL dp[N][30];
 24 int ans[N];
 25 struct node
 26 {
 27     LL dis,val;
 28     int id;
 29 } a[N],b[N];
 30 bool cmp(struct node a,struct node b)
 31 {
 32     if(a.dis!=b.dis)return a.dis<b.dis;
 33     else return a.val>b.val;
 34 }
 35 void RMQ(int n)
 36 {
 37     for(int i=1; i<=n; i++)dp[i][0]=a[i].val;
 38     for(int j=1; (1<<j)<=n; j++)
 39     {
 40         for(int i=1; (i+(1<<j)-1)<=n; i++)
 41         {
 42             dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
 43         }
 44     }
 45 }
 46 LL query(int l,int r)
 47 {
 48     int k=0;
 49     while((1<<(k+1))<=(r-l+1))k++;
 50     return max(dp[l][k],dp[r-(1<<k)+1][k]);
 51 }
 52 struct node found(int l,int r,LL Val)//you
 53 {
 54     int mid;
 55     struct node p1;
 56     LL V;
 57     while(l<r)
 58     {
 59         mid=(l+r)/2;
 60         V=query(l,mid);
 61         if(V>Val)
 62         {
 63             r=mid;
 64         }
 65         else
 66         {
 67             l=mid+1;
 68         }
 69     }
 70     //cout<<l<<" "<<r<<endl;
 71     if(a[l].val>Val)p1=a[l];
 72     else p1.id=-1;
 73     return p1;
 74 }
 75 struct node found1(int l,int r,LL Val)//you
 76 {
 77     int mid;
 78     struct node p1;
 79     LL V;
 80     while(l<=r)
 81     {
 82         mid=(l+r)/2;
 83         V=query(mid,r);
 84         if(V>Val)
 85         {
 86             l=mid+1;
 87         }
 88         else
 89         {
 90             r=mid-1;
 91         }
 92     }
 93     //cout<<l<<" "<<r<<endl;
 94     if(a[r].val>Val)p1=a[r];
 95     else p1.id=-1;
 96     return p1;
 97 }
 98 int main()
 99 {
100 #ifdef Local
101     freopen("data","r",stdin);
102 #endif
103     int i,j,k,n;
104     cin>>n;
105     for(i=1; i<=n; i++)
106     {
107         scanf("%lld%lld",&a[i].dis,&a[i].val);
108         a[i].id=i;
109         b[i]=a[i];
110     }
111     sort(a+1,a+n+1,cmp);
112     RMQ(n);
113     for(i=1; i<=n; i++)
114     {
115         int l,r,mid;
116         struct node p1,p2;
117         p1.id=-1;p2.id=-1;
118         LL V;
119         l=1;
120         r=i;
121         p1=found1(l,r,a[i].val);
122         l=i;r=n;
123         p2=found(l,r,a[i].val);
124         //cout<<i<<" "<<p1.id<<" "<<p2.id<<endl;
125         if(p2.id==-1&&p1.id==-1)ans[a[i].id]=-1;
126         else if(p1.id==-1&&p2.id!=-1)ans[a[i].id]=p2.id;
127         else if(p1.id!=-1&&p2.id==-1)ans[a[i].id]=p1.id;
128         else
129         {
130             if(abs(a[i].dis-p1.dis)>abs(a[i].dis-p2.dis))
131             {
132                 ans[a[i].id]=p2.id;
133             }
134             else if(abs(a[i].dis-p1.dis)<abs(a[i].dis-p2.dis))
135             {
136                 ans[a[i].id]=p1.id;
137             }
138             else
139             {
140                 if(p1.val>p2.val)ans[a[i].id]=p1.id;
141                 else ans[a[i].id]=p2.id;
142             }
143         }
144     }
145     for(i=1;i<=n;i++)
146     {
147         if(i==n)printf("%d\n",ans[i]);
148         else printf("%d ",ans[i]);
149     }
150 }


				
时间: 2024-10-05 21:31:57

Code Forces Gym 100971D Laying Cables(单调栈)的相关文章

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

Gym 100971D Laying Cables

要求找出每个a[i],找到离他最近而且权值比它大的点,若距离相同,输出权利最大的那个 我的做法有点复杂,时间也要500+ms,因为只要时间花在了map上. 具体思路是模拟一颗树的建立过程,对于权值最大的那个,必须是-1,次大的那个,必须是pos_peo[mx]:就是最大人口的节点id. 然后维护一个单调的序列,记录当前有多少个位置加入了树.用个set保证单调性.小到大 把结构体按人口排序大到小,枚举没个城市,这样保证加入后,后面加入的直接找位置最短即可,人口最对的bigger than now的

Code Forces Gym 100886J Sockets

J - Sockets Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Valera has only one electrical socket in his flat. He also has m devices which require electricity to work. He's got n plug multipliers to plug the devices, the

Gym 101102D---Rectangles(单调栈)

题目链接 http://codeforces.com/gym/101102/problem/D problem  description Given an R×C grid with each cell containing an integer, find the number of subrectangles in this grid that contain only one distinct integer; this means every cell in a subrectangle

BZOJ 3238 AHOI 2013 差异 后缀数组+单调栈

题目大意: 思路:一看各种后缀那就是后缀数组没跑了. 求出sa,height之后就可以乱搞了.对于height数组中的一个值,height[i]来说,这个值能够作为lcp值的作用域只在左边第一个比他小的位置到右边第一个比他小的位置.这个东西很明显可以倍增RMQ+二分/单调栈. 之后就是数学题了 Σlen[Ti] + len[Tj] = (len + 1) * len * (len - 1),之后吧所有求出来的Σ2 * lcp(Ti,Tj)减掉就是答案. 记得答案开long long CODE:

【BZOJ-3956】Count ST表 + 单调栈

3956: Count Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 173  Solved: 99[Submit][Status][Discuss] Description Input Output Sample Input 3 2 0 2 1 2 1 1 1 3 Sample Output 0 3 HINT M,N<=3*10^5,Ai<=10^9 Source CH Round#64 MFOI杯水题欢乐赛day1 By Gromah So

基础算法复习——单调栈

单调栈: 单调栈非常容易理解,因为栈只能从一个方向进出. 单调栈的作用主要是可以找到一个数左边或右边第一个比它大或比它小的数. 下面以找出一个数左边第一个比它大的数为例. 举一列数:3,7,4,9,2,1 从左向右进行循环,(注意:入栈的是数组下标.在第一个元素入栈之前先把0入栈,在这里把a[0]的值设为无穷大) 对a[1],3比无穷大小,所以ans[1]=0,1入栈. 对a[2],7比3大,3出栈,所以ans[2]=0,2入栈 ...... 以此类推 Code: 1 for (int i=1;

RQNOJ 429 词链:单调栈

题目链接:https://www.rqnoj.cn/problem/429 题意: 如果一张由一个词或多个词组成的表中,每个单词(除了最后一个)都是排在它后面的单词的前缀,则称此表为一个词链. 如:i,int,integer. 给你一堆按字典序排好的字符串,问你最长的词链有多长(词链中的字符串个数). 题解: 单调栈. 找出单调性: 对于栈内的元素,从栈底到栈顶为单调,形成一个词链. 找出答案: 扫一遍给出的字符串,栈的最大高度即为答案. 维护单调性: 因为字符串按字典序排好,已经达到了是单调性

NOJ1175---Dress, Left Dress!(单调栈)

Maybe you think this problem is about girls and ladies. But you're wrong. 'Left dress' means 'Eyes left'. It's used in armed forces. It will make a square more orderly. Now several soldiers stand in a line. They are in diffient height or the same. Wh