您的位置:首页 > 产品设计 > UI/UE

SPOJ - LIS2 Another Longest Increasing Subsequence Problem

2015-12-02 08:43 495 查看
cdq分治,dp(i)表示以i为结尾的最长LIS,那么dp的递推是依赖于左边的。

因此在分治的时候需要利用左边的子问题来递推右边。

(345ms? 区间树TLE

/*********************************************************
*            ------------------                          *
*   author AbyssFish                                     *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
#include<numeric>
using namespace std;

const int MAX_N = 100000+5;

int dp[MAX_N];
int x[MAX_N], y[MAX_N];
int ys[MAX_N];
int id[MAX_N];
int N;

int ns;

int *cur;
bool cmp(int a,int b)
{
return cur[a] < cur[b] || (cur[a] == cur[b] && a > b);//这是为了保证严格的单调性
}

int compress(int *r, int *dat, int *a, int n)
{
for(int i = 0; i < n; i++){
r[i] = i;
}
cur = dat;
sort(r,r+n,cmp);
a[r[0]] = 1;
for(int i = 1; i < n; i++){
int k = r[i], p = r[i-1];
a[k] = dat[k] == dat[p]?a[p]:a[p]+1;
}
return a[r[n-1]];
}

int C[MAX_N];

void add(int yi,int d)
{
while(yi <= ns){
C[yi] = max(C[yi],d);
yi += yi&-yi;
}
}

int mx_pfx(int yi)
{
int re = 0;
while(yi > 0){
re = max(C[yi],re);
yi &= yi-1;
}
return re;
}

void clr(int yi)
{
while(yi <= ns){
C[yi] = 0;
yi += yi&-yi;
}
}

void dv(int l, int r)
{
if(r-l <= 1){
dp[l]++;
}
else {
int md = (l+r)>>1;
dv(l,md);

for(int i = l; i < r; i++) id[i] = i;
sort(id+l,id+r,cmp); //x维度

for(int i = l; i < r; i++){
int k = id[i];
if(k < md){ //position 维度
add(ys[k],dp[k]); //BIT下标是 y维度
}
else {
//查询位置前保证了BIT里的元素, 位置md之前,x严格小于待查元素
dp[k] = max(dp[k], mx_pfx(ys[k]-1));//y严格小于待查元素的最大dp值
}
}

for(int i = l; i < r; i++){
if(id[i] < md)
clr(ys[id[i]]);
}
dv(md,r);
}
}

void solve()
{
scanf("%d",&N);
for(int i = 0; i < N; i++){
scanf("%d%d",x+i,y+i);
}
ns = compress(id,y,ys,N);
cur = x;
dv(0,N);
printf("%d\n",*max_element(dp,dp+N));
}

//#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: