Acdream 1126 Beautiful People(最长上升子序列,dp+线段树优化)

来源:互联网 发布:网络推广框架协议 编辑:程序博客网 时间:2024/05/16 12:25

先按x排序,对于相同的x分块处理,也就是x相同的一起处理。dp[i]=dp[j]+1,由于x相同是一起处理所以只要a[i]>a[j]即可。

建议先看一下本博客里的LIS线段树优化的文章。

 

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;struct pi{    int x;    int y;    int id;}pp[100005];int a[100005];int dp[100005];int b[100005];int cmp(pi a,pi b){    if(a.x!=b.x) return a.x<b.x;    return a.y<b.y;}int get(int x,int y,int n){    int le,ri,mid;    le=1;    ri=n;    while(le<=ri){        mid=(le+ri)/2;        if(pp[b[mid]].y<y&&pp[b[mid]].x<x) le=mid+1;        else ri=mid-1;    }    return le;}struct ppi{    int le;    int ri;    int max;    int m;}pp1[400005];void build(int tot,int l,int r){    pp1[tot].le=l;    pp1[tot].ri=r;    pp1[tot].max=0;    pp1[tot].m=-1;    if(l==r) return ;    build(2*tot,l,(l+r)/2);    build(2*tot+1,(l+r)/2+1,r);}void merg(int tot,int p,int m,int id){    if(pp1[tot].le==pp1[tot].ri){        if(pp1[tot].max<m){            pp1[tot].max=m;            pp1[tot].m=id;        }        return ;    }    int mid;    mid=(pp1[tot].le+pp1[tot].ri)/2;    if(p<=mid){        merg(2*tot,p,m,id);    }    else{        merg(2*tot+1,p,m,id);    }    if(pp1[2*tot].max<pp1[2*tot+1].max){            pp1[tot].max=pp1[2*tot+1].max;            pp1[tot].m=pp1[2*tot+1].m;    }    else{            pp1[tot].max=pp1[2*tot].max;            pp1[tot].m=pp1[2*tot].m;    }}int query(int tot,int n){    if(pp1[tot].le>=1&&pp1[tot].ri<=n){        return pp1[tot].m;    }    int x,y;    int mid;    mid=(pp1[tot].le+pp1[tot].ri)/2;    x=-1;    y=-1;    x=query(2*tot,n);    if(n>mid){        y=query(2*tot+1,n);    }    if(x==-1) return y;    if(y==-1) return x;    if(dp[x]<dp[y]) return y;    return x;}int main(){    int i,n,m,k,p,tot,j,f;    while(cin>>n){        tot=0;        for(i=1;i<=n;i++){            scanf("%d%d",&pp[i].x,&pp[i].y);            pp[i].id=i;            b[++tot]=pp[i].y;        }        sort(pp+1,pp+1+n,cmp);        sort(b+1,b+tot+1);        m=tot;        build(1,1,m);        for(i=1;i<=n;i++){            p=i;            while(p<n&&pp[p].x==pp[p+1].x) p++;            for(j=i;j<=p;j++){                if(i==1){                    dp[j]=1;                    a[j]=-1;                }                else{                    k=lower_bound(b+1,b+1+m,pp[j].y)-b;                    if(k==1){                        dp[j]=1;                        a[j]=-1;                    }                    else{                        f=query(1,k-1);                        if(f==-1){                            dp[j]=1;                            a[j]=-1;                            continue;                        }                        a[j]=f;                        dp[j]=dp[f]+1;                    }                }            }            for(j=i;j<=p;j++){                k=lower_bound(b+1, b+1+m, pp[j].y)-b;                merg(1,k,dp[j],j);            }            i=p;        }        p=0;        for(i=1;i<=n;i++){            p=max(p,dp[i]);        }        for(i=1;i<=n;i++){            if(dp[i]==p){                printf("%d\n",p);                printf("%d",pp[i].id);                k=a[i];                while(k!=-1){                    printf(" %d",pp[k].id);                    k=a[k];                }                printf("\n");                break;            }        }    }}

0 0
原创粉丝点击