51nod 1105 第K大的数

来源:互联网 发布:3m互助系统源码 编辑:程序博客网 时间:2024/06/05 06:20

题意就不说了。。我真是菜哭了,四级都不能随手切,,感觉NOIP药丸。。。
一眼二分,但是怎么判断一直没有想到、、后来看了别人的题解才知道tmd原来是log方的,亏我一直在想log的,,,其实看看数据范围就知道是可以log方。。。判断就是直接判断,,,先把a和b排序,然后确定当前二分的数所在的范围(即是由a中的哪个数组成的),然后再二分b中匹配的位置,然后每次用n减去,就是小于当前二分数的数字的数量。。。然后就能直接二分判断了,,我真是傻。。

uses math;var        i,j:longint;        p,n,m,k,ans,l,r,mid:int64;        a,b:array[0..100000]of int64;procedure qsort(l,r:longint);var        i,j:longint;        t,m:int64;begin        i:=l;        j:=r;        m:=a[(l+r)div 2];        repeat                while a[i]<m do inc(i);                while a[j]>m do dec(j);                if i<=j then                begin                        t:=a[i];                        a[i]:=a[j];                        a[j]:=t;                        inc(i);                        dec(j);                end;        until i>j;        if l<j then qsort(l,j);        if i<r then qsort(i,r);end;procedure qsort1(l,r:longint);var        i,j:longint;        t,m:int64;begin        i:=l;        j:=r;        m:=b[(l+r)div 2];        repeat                while b[i]<m do inc(i);                while b[j]>m do dec(j);                if i<=j then                begin                        t:=b[i];                        b[i]:=b[j];                        b[j]:=t;                        inc(i);                        dec(j);                end;        until i>j;        if l<j then qsort1(l,j);        if i<r then qsort1(i,r);end;function search(y,x:int64):int64;var        i,j:longint;        ans,l,r,mid:int64;begin        l:=1;        r:=n;        ans:=n;        while l<=r do        begin                mid:=(l+r)div 2;                if a[y]*b[mid]>=x then                begin                        ans:=min(ans,mid);                        r:=mid-1;                end                else begin                        l:=mid+1;                end;        end;        exit(ans);end;function check(x:int64):boolean;var        i,j,ans:longint;begin        ans:=0;        for i:=1 to n do        begin                if a[i]*b[n]<x then continue;                ans:=ans+n-search(i,x)+1;        end;        if ans>=m then exit(true)        else exit(false);end;begin        readln(n,m);        for i:=1 to n do read(a[i],b[i]);        qsort(1,n);        qsort1(1,n);        l:=a[1]*b[1];        r:=a[n]*b[n];        while l<=r do        begin                mid:=(l+r)div 2;                if check(mid)then                begin                        l:=mid+1;                        ans:=mid;                end                else begin                        r:=mid-1;                end;        end;        writeln(ans);end.
0 0