1. 程式人生 > >SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三維偏序)

SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三維偏序)

lines out nes 三維 seq find DC 別人 d+

Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it.

An increasing sequence A1..An is a sequence such that for every i < j, Ai < Aj.

A subsequence of a sequence is a sequence that appears in the same relative order, but not necessarily contiguous.

A pair of integers (x1, y1) is less than (x2, y2) iff x1 < x2 and y1 < y2.

Input

The first line of input contains an integer N (2 ≤ N ≤ 100000).

The following N lines consist of N pairs of integers (xi, yi) (-109xi, yi ≤ 109).

Output

The output contains an integer: the length of the longest increasing subsequence of the given sequence.

Example

Input:
8
1 3
3 2
1 1
4 5
6 3
9 9
8 7
7 6

Output:
3

題意;求最長的序列LIS,滿足i<j,xi<xj ;yi<yj。

思路:裸題,cqd分治,計算每個[L,Mid]區間對[Mid+1,R]區間的貢獻。

有兩個註意點:

第一:由於時間緊,只有300ms,不能寫結構體的排序; 這裏借鑒了別人的一維排序(ORZ,強的啊)。

第二:註意規避x1=x2,y1<y2的時候不能用 1去更新2。(和求逆序對那題一樣,只有把y坐標的放左邊即可)。

#include<bits/stdc++.h>
using
namespace std; const int maxn=1000010; int p[maxn],a[maxn],b[maxn],dp[maxn],Mx[maxn],tot,ans; bool cmp(int x,int y){ if(a[x]==a[y]) return x>y; return a[x]<a[y]; } void solve(int L,int R) { if(L==R){ dp[L]=max(dp[L],1); return ;} int Mid=(L+R)/2; solve(L,Mid); for(int i=L;i<=R;i++) p[i]=i; sort(p+L,p+R+1,cmp); for(int i=L;i<=R;i++){ if(p[i]<=Mid) for(int j=b[p[i]];j<=tot;j+=(-j)&j) Mx[j]=max(Mx[j],dp[p[i]]); else for(int j=b[p[i]]-1;j;j-=(-j)&j) dp[p[i]]=max(dp[p[i]],Mx[j]+1); } for(int i=L;i<=R;i++) if(p[i]<=Mid) for(int j=b[p[i]];j<=tot;j+=(-j)&j) Mx[j]=0; solve(Mid+1,R); } int main() { int N,i,fcy=0; scanf("%d",&N); for(i=1;i<=N;i++) scanf("%d%d",&a[i],&b[i]),p[i]=b[i]; sort(p+1,p+N+1); tot=unique(p+1,p+N+1)-(p+1); for(i=1;i<=N;i++) b[i]=lower_bound(p+1,p+tot+1,b[i])-p; solve(1,N); for(i=1;i<=N;i++) fcy=max(fcy,dp[i]); printf("%d\n",fcy); return 0; }

SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三維偏序)