区间 纪中 1382 最长不上升子序列o(n logn)

来源:互联网 发布:韩顺平qq项目源码微盘 编辑:程序博客网 时间:2024/06/04 08:50

Description

  Alice收到一些很特别的生日礼物:区间。即使很无聊,Alice还是能想出关于区间的很多游戏,其中一个是,Alice从中选出最长的不同区间的序列,其中满足每个区间必须在礼物中,另序列中每个区间必须包含下一个区间。
  编程计算最长序列的长度。

Input

  输入文件第一行包含一个整数N(1<=N<=100000),表示区间的个数。
  接下来N行,每行两个整数A和B描述一个区间(1<=A<=B<=1000000)。

Output

  输出满足条件的序列的最大长度。

Sample Input

输入1:

3

3 4

2 5

1 6

输入2:

5

10 30

20 40

30 50

10 60

30 40

输入3:

6

1 4

1 5

1 6

1 7

2 5

3 5

Sample Output

输出1:

3

输出2:

3

输出3:

5

分析

隔壁的第一眼:
这尼玛不是最长不上升子序列么!!!

隔壁的第二眼:
这尼玛就是最长不上升子序列!!!
本着 竭尽所能的原则,他想都不想就打了O(n²)的原版。
于是n=100000的数据令他的代码

瞬间爆炸

所以,本着(抄标)学习的精神
我们找的o(n logn)的算法:点一下

话说我的快排和二分错了很久

代码

type  arry=array[0..100010] of longint;var  x,y:array[0..100010] of longint;  f,b:array[0..100010] of longint;  ans:longint;  ls:longint;  i,j,k:longint;  n:longint;function fdfdfd(l,r,x:longint):longint;var  i,j,k:longint;  mid:longint;begin  i:=l; j:=r;  while i<=j do    begin      mid:=i+(j-i) div 2;      if b[mid]>=x then i:=mid+1                   else j:=mid-1;    end;  fdfdfd:=i;end;procedure qsort(var a,b:arry; l,r:longint);var  i,j,k:longint;  mid,zzt:longint;  temp:longint;begin  if l>=r then exit;  i:=l; j:=r;  mid:=a[(l+r) div 2];  zzt:=b[(l+r) div 2];  repeat    while (a[i]<mid) or ((a[i]=mid)and(b[i]>zzt)) do i:=i+1;    while (a[j]>mid) or ((a[j]=mid)and(b[j]<zzt)) do j:=j-1;    if i<=j      then        begin          temp:=a[i]; a[i]:=a[j]; a[j]:=temp;          temp:=b[i]; b[i]:=b[j]; b[j]:=temp;          i:=i+1; j:=j-1;        end;  until i>j;  qsort(a,b,l,j);  qsort(a,b,i,r);end;begin  readln(n);  for i:=0 to n do    b[i]:=-maxlongint;  for i:=1 to n do    begin      readln(x[i],y[i]);    end;  qsort(x,y,1,n);  for i:=1 to n do    begin      j:=fdfdfd(1,i,y[i]);      f[i]:=j;      if b[f[i]]<y[i] then b[f[i]]:=y[i];    end;  ans:=0;  for i:=1 to n do    if ans<f[i] then ans:=f[i];  write(ans);end.
1 0
原创粉丝点击