题目描述
最近 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。
题解
线段树。
题意其实就是按输入顺序找出几个区间使它们覆盖[ 1,n ] 。
那么找到的第一个区间的左端点一定是 1 。
以后每个区间的答案可以由它覆盖到的前面的区间的最小答案+1更新而来。
复杂度O(mlogn)。
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=50000+50; const int inf=2e9; int n,m,pos[maxn]; struct SegmentTree{int l,r,mn;}st[maxn<<2]; void pushup(int root){ st[root].mn=min(st[root<<1].mn,st[root<<1|1].mn); } void build(int root,int l,int r){ st[root].l=l;st[root].r=r; if(l==r){ pos[l]=root; if(l==1) st[root].mn=0; else st[root].mn=inf; } else{ int m=l+r>>1; build(root<<1,l,m);build(root<<1|1,m+1,r); pushup(root); } } int query(int root,int l,int r){ if(st[root].l>r||st[root].r<l) return inf; if(st[root].l>=l&&st[root].r<=r) return st[root].mn; return min(query(root<<1,l,r),query(root<<1|1,l,r)); } void update(int x,int val){ int root=pos[x]; st[root].mn=min(st[root].mn,val); while(root>>=1&&root) pushup(root); } template<typename T>void read(T& aa){ char cc; ll ff;aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } int main(){ // freopen("sorter.in","r",stdin); // freopen("sorter.out","w",stdout); read(n),read(m); build(1,1,n); while(m--){ int l,r; read(l),read(r); if(l==r) continue; update(r,query(1,l,r-1)+1); } if(st[pos[n]].mn!=inf){ cout<<st[pos[n]].mn<<endl; } else cout<<-1<<endl; // noip 2018 rp ++ return 0; }