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
4
1 1000
7 10
9 1
12 100
-1 4 2 1
3
1 100
2 1
3 10
-1 1 1
3
1 10
3 100
2 1
2 -1 2 题意:给定一维数轴上的N个点和对应的权值,同时定义一个点的父亲为:离它最近且权值比它大的点下标,如果距离相同则选择权值较大的,如果没有则为-1,求出所有点的父亲? 思路1:单调栈预处理出左边和右边第一个比它大的元素的下标即可。
单调栈的作用:求出某个数的左边或右边第一个比它大或比它小的元素,复杂度O(n)。
单调递增栈:元素从栈底到栈顶严格单调递增。
单调递减栈:元素从栈底到栈顶严格单调递减。 代码1:
#include <iostream>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
#define mt(A,B) memset(A,B,sizeof(A))
#define mod 1000000007
using namespace std;
typedef long long LL;
const int N=+;
const LL INF=0x3f3f3f3f3f3f3f3fLL;
LL val[N],id[N],x[N],ans[N],S[N],L[N],R[N];//S[N]表示单调栈
bool cmp(LL a,LL b)
{
return x[a]<x[b];
}
int main()
{
#ifdef Local
freopen("data.txt","r",stdin);
#endif
ios::sync_with_stdio();
LL i,j,k,n;
cin>>n;
for(i=;i<=n;i++)
{
cin>>x[i]>>val[i];//x[i]表示在数轴上的位置,val[i]表示该点的价值
id[i]=i;
}
sort(id+,id++n,cmp);//按在数轴上的位置从小到大排序
k=;S[k++]=;val[]=2e9;//先把INF压入栈底
for(i=;i<=n;i++)
{
while(val[S[k-]]<=val[id[i]])k--;//如果当前的val比栈顶的大,就把栈顶的元素弹出来
L[id[i]]=S[k-];//找到了左边第一个比他大的数的下标
S[k++]=id[i];//把当前的下标压入栈
}
k=n+;S[k--]=n+;val[n+]=2e9;
for(i=n;i>=;i--)//同理
{
while(val[S[k+]]<=val[id[i]])k++;
R[id[i]]=S[k+];
S[k--]=id[i];
}
for(i=;i<=n;i++)
{
if(L[i]==&&R[i]==n+)ans[i]=-;
else if(L[i]==)ans[i]=R[i];
else if(R[i]==n+)ans[i]=L[i];
else
{
if(abs(x[L[i]]-x[i])<abs(x[R[i]]-x[i]))ans[i]=L[i];
else if(abs(x[L[i]]-x[i])>abs(x[R[i]]-x[i]))ans[i]=R[i];
else
{
if(val[L[i]]<val[R[i]])ans[i]=R[i];
else if(val[L[i]]>val[R[i]])ans[i]=L[i];
}
}
}
for(i=;i<=n;i++)
{
if(i==n)cout<<ans[i]<<endl;
else cout<<ans[i]<<" ";
}
}
思路2:先按数轴上的位置排序,RMQ预处理区间的最大值,再往左往右二分。训练的时候并不会单调栈,所以只能用RMQ二分瞎几把乱搞。
代码2:
#include <iostream>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
#define mod 1000000007
#define mt(A) memset(A,0,sizeof(A))
using namespace std;
typedef long long LL;
const int N=+;
const LL INF=0x3f3f3f3f3f3f3f3fLL;
LL dp[N][];
int ans[N];
struct node
{
LL dis,val;
int id;
} a[N],b[N];
bool cmp(struct node a,struct node b)
{
if(a.dis!=b.dis)return a.dis<b.dis;
else return a.val>b.val;
}
void RMQ(int n)
{
for(int i=; i<=n; i++)dp[i][]=a[i].val;
for(int j=; (<<j)<=n; j++)
{
for(int i=; (i+(<<j)-)<=n; i++)
{
dp[i][j]=max(dp[i][j-],dp[i+(<<(j-))][j-]);
}
}
}
LL query(int l,int r)
{
int k=;
while((<<(k+))<=(r-l+))k++;
return max(dp[l][k],dp[r-(<<k)+][k]);
}
struct node found(int l,int r,LL Val)//you
{
int mid;
struct node p1;
LL V;
while(l<r)
{
mid=(l+r)/;
V=query(l,mid);
if(V>Val)
{
r=mid;
}
else
{
l=mid+;
}
}
//cout<<l<<" "<<r<<endl;
if(a[l].val>Val)p1=a[l];
else p1.id=-;
return p1;
}
struct node found1(int l,int r,LL Val)//you
{
int mid;
struct node p1;
LL V;
while(l<=r)
{
mid=(l+r)/;
V=query(mid,r);
if(V>Val)
{
l=mid+;
}
else
{
r=mid-;
}
}
//cout<<l<<" "<<r<<endl;
if(a[r].val>Val)p1=a[r];
else p1.id=-;
return p1;
}
int main()
{
#ifdef Local
freopen("data","r",stdin);
#endif
int i,j,k,n;
cin>>n;
for(i=; i<=n; i++)
{
scanf("%lld%lld",&a[i].dis,&a[i].val);
a[i].id=i;
b[i]=a[i];
}
sort(a+,a+n+,cmp);
RMQ(n);
for(i=; i<=n; i++)
{
int l,r,mid;
struct node p1,p2;
p1.id=-;p2.id=-;
LL V;
l=;
r=i;
p1=found1(l,r,a[i].val);
l=i;r=n;
p2=found(l,r,a[i].val);
//cout<<i<<" "<<p1.id<<" "<<p2.id<<endl;
if(p2.id==-&&p1.id==-)ans[a[i].id]=-;
else if(p1.id==-&&p2.id!=-)ans[a[i].id]=p2.id;
else if(p1.id!=-&&p2.id==-)ans[a[i].id]=p1.id;
else
{
if(abs(a[i].dis-p1.dis)>abs(a[i].dis-p2.dis))
{
ans[a[i].id]=p2.id;
}
else if(abs(a[i].dis-p1.dis)<abs(a[i].dis-p2.dis))
{
ans[a[i].id]=p1.id;
}
else
{
if(p1.val>p2.val)ans[a[i].id]=p1.id;
else ans[a[i].id]=p2.id;
}
}
}
for(i=;i<=n;i++)
{
if(i==n)printf("%d\n",ans[i]);
else printf("%d ",ans[i]);
}
}
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 h ...
- Gym 100971D Laying Cables 二分 || 单调栈
要求找出每个a[i],找到离他最近而且权值比它大的点,若距离相同,输出权利最大的那个 我的做法有点复杂,时间也要500+ms,因为只要时间花在了map上. 具体思路是模拟一颗树的建立过程,对于权值最大 ...
- Codeforces gym 100971 D. Laying Cables 单调栈
D. Laying Cables time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Gym - 101102D Rectangles (单调栈)
Given an R×C grid with each cell containing an integer, find the number of subrectangles in this gri ...
- Code Forces Gym 100886J Sockets(二分)
J - Sockets Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Valera ...
- D - Laying Cables Gym - 100971D (单调栈)
题目链接:https://cn.vjudge.net/problem/Gym-100971D 题目大意:给你n个城市的信息,每一个城市的信息包括坐标和人数,然后让你找每一个城市的父亲,作为一个城市的父 ...
- Gym 100971D 单调栈
D - Laying Cables Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u ...
- Gym 101102D---Rectangles(单调栈)
题目链接 http://codeforces.com/gym/101102/problem/D problem description Given an R×C grid with each cel ...
- Gym - 101334F 单调栈
当时我的第一想法也是用单调栈,但是被我写炸了:我也不知道错在哪里: 看了大神的写法,用数组模拟的: 记录下单调递增栈的下标,以及每个数字作为最小值的最左边的位置. 当有数据要出栈的时候,说明栈里的数据 ...
随机推荐
- IE6背景图片闪动问题
在IE6中,当JS触发事件时或者hover的时候,如果网速过慢 IE6背景图片重新加载会闪一下. 好的一个解决方案是 <!--[if IE 6]><script> try{do ...
- 在Windows下不使用密码远程登陆Linux
在登陆Linux进行管理的时候我们通常会使用用户名和密码进行登陆,这样一来是比较麻烦,二来是不安全,为了解决这个问题,我们可以使用公私钥 (public keys和private keys)进行认证. ...
- Linux grep和find的区别
这是两个不同的命令,关于grep:Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expressi ...
- Class TBoundlabel not found and so on..
Class TBoundlabel not found when you put a labeledit into a panel of CategoryPanel then you'll found ...
- (转载)delphi实例TDBGrid用右键菜单复制行粘贴行
delphi实例TDBGrid用右键菜单复制行粘贴行 这个从本质上来说就是DBGrid后台数据库的插入 右键复制当前行的相关数据到临时变量点粘贴时,覆盖数据或插入数据! db为数据库: 字段名id,n ...
- Python全栈开发之MySQL(三)视图,存储过程触发器,函数,事务,索引
一:视图 1:什么是视图? 视图是指存储在数据库中的查询的SQL语句,具有简单.安全.逻辑数据独立性的作用及视点集中简化操作定制数据安全性的优点.视图包含一系列带有名称的列和行数据.但是,视图并不在数 ...
- Word续上表
选中表格的下半部分(全部下半部分),然后按ctrl+shift+enter,这样就换行了.
- Http 与 Socket 区别
HTTP:超文本传输协议,首先它是一个协议,并且是基于TCP/IP协议基础之上的应用层协议.TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,HTTP是应用层协议,主要解决如何包装数据.HT ...
- Ubuntu修改语言环境为英文
转自把语言环境变量改为英文 将Ubuntu系统语言环境改为英文的en_US.UTF-8 查看当前系统语言环境 locale 编辑配置文件,将zh_US.UTF-8改为en_US.UTF-8,zh改为e ...
- phpstorm 强大的活动模板 可以自定义注释,代码段,根据cms订制自动提示
http://jingyan.baidu.com/article/8275fc86badd6346a03cf6aa.html [PHP] phpstorm的使用(1) http://v.youku.c ...