P4214 [JZOJ]SERN的野望

能看懂题目的孩子真不容易。

题目描述 : 如果有一个集合 \(X\{\},Y\{\}\) (任意位置) 保证 \(X_i > a,Y_i > b\),那么 \(ans_{a,b}=\max{ans_{X\{\},Y\{\}}}+1\)

一眼看过去,难道是三维偏序?
\(\texttt{CDQ}\) 一下?

再看过去,难道是二维偏序?
\(\texttt{CDQ}\) 一下?

再看过去,是二维偏序的变种?
从下到上 \(\texttt{CDQ}\) 一下?

上面三句话纯属扯淡,当然你是可以在我的提交记录里面看到这个东西的:

我们发现其实我们按照第一关键字排序后,答案就为第二关键字所在的最长下降子序列的长度里。

因为快排而搞了 \(1h\) 的我。

Const
    total=100000 << 1;

var
    ans,order:array[-1..total] of longint;
    num:array[-1..total,1..3] of longint;
    i,j,n,m,l,r,mid,tail:longint;

procedure Swap(var x,y:longint);var t:longint; begin t:=x; x:=y; y:=t; end;

procedure Sort(l,r:longint);
var i,j,s:longint;
begin
    i:=l; j:=r; s:=num[(l+r) >> 1,1];
    repeat
        while (num[i,1]>s) do inc(i);
        while (num[j,1]<s) do dec(j);
        if i<=j then
        begin 
            Swap(num[i,1],num[j,1]); Swap(num[i,2],num[j,2]); Swap(num[i,3],num[j,3]);
            inc(i); dec(j);
        end;
    until i>=j;
    if i<r then Sort(i,r);
    if j>l then Sort(l,j);
end;

begin
    read(n);
    for i:=1 to n do begin read(num[i,1],num[i,2]); num[i,3]:=i; end;
    Sort(1,n); num[0]:=num[-1];
    for i:=1 to n do
    begin
        l:=1; r:=tail;
        while l<=r do
        begin
            mid:=(l+r) >> 1;
            if ans[mid]<num[i,2] then r:=mid-1 else l:=mid+1;
        end;
        inc(r); if r>tail then inc(tail);
        ans[r]:=num[i,2]; order[num[i,3]]:=r; 
    end;
    for i:=1 to n do writeln(order[i],' ');
end.
posted @ 2019-04-04 19:57  Rattry  阅读(175)  评论(0)    收藏  举报