您的位置:首页 > 理论基础 > 计算机网络

全国信息学奥林匹克联赛(NOIP2016 )复赛模拟(二)

2016-10-06 20:43 239 查看
排序网络
Sorter


【问题描述】

最近 Henryy 公司推出了新型的排序网络。简单的来说,这种排序网络是由

一系列的的排序器按顺序组成。某个排序器可以将排序网络中[L,R]之间的输入

端进行排序。经过排序器处理后[L,R]之间排成非递减顺序。不同排序器的 L、R

值不同。

虽然排序网络很有用,但是很多情况下面我们可能只要排序网络中的最大

值,所以 Henryy 公司决定利用已有的排序网络再开发一个只求最大值的网络。

改造方法很简单,只需要隐蔽原有网络中的某些排序器,使得最后一个输入端的

值是最大值。这样一来既可以减少开发成本,又可以降低网络的功耗。

现在的任务是,给定 N 个不同的排序器,要求你改造这个网络,使得网络

最后一个输入端经过操作后是这个网络的最大值。要求使用的排序器要尽可能

少。 (也就是说,不能改变原来排序网络的结构,你可以选择某个排序器是否隐

蔽)

【 输入文件】 】

第一行是两个数 N,M。N 表示排序网络有 N 个输入端。接下来将会有 M

行,每行 2 个数 Li,Ri,分别表示排序器 I 排序的范围[Li,Ri]。 (,

1<=Li<=Ri<=N)

【 输出文件】 】

输出一个数 P,表示使用的最少排序器。-1 表示无解(由于设计缺陷) 。

【 样例输入】 】

40 6

20 30

1 10

10 20

20 30

15 25

30 40

【 样例输出】 】

4

【 数据约定】 】

0≤N≤50000,0≤M≤500000。

对于 30%的数据有 N≤100。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;
const int N=50010;
int Min[N<<2],pos
;
#define mid (l+r>>1)
void Build(int x,int l,int r){
if(l==r){
pos[l]=x;
if(l==1)Min[x]=0;
else Min[x]=(int)1e9;
}
else{
Build(x<<1,l,mid);
Build(x<<1|1,mid+1,r);
Min[x]=min(Min[x<<1],Min[x<<1|1]);
}
}
int Query(int x,int l,int r,int a,int b){
if(l>=a&&r<=b)return Min[x];int ret=(int)1e9;
if(mid>=a)ret=min(ret,Query(x<<1,l,mid,a,b));
if(mid<b)ret=min(ret,Query(x<<1|1,mid+1,r,a,b));
return ret;
}
void Update(int g,int d){
int x=pos[g];Min[x]=min(Min[x],d);
while(x>>=1,x)Min[x]=min(Min[x<<1],Min[x<<1|1]);
}
int n,m,l,r;
int main(){
freopen("sorter.in","r",stdin);
freopen("sorter.out","w",stdout);
scanf("%d%d",&n,&m);
Build(1,1,n);
while(m--){
scanf("%d%d",&l,&r);
if(l==r)continue;
Update(r,Query(1,1,n,l,r-1)+1);
}
if(Min[pos
]!=((int)1e9))
printf("%d\n",Min[pos
]);
else
puts("-1");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息