[P2757]导弹的召唤

来源:互联网 发布:海中金seo 编辑:程序博客网 时间:2024/04/28 15:13

原题链接

导弹拦截数据加强版
nlogn的最长上升/不上升子序列

先设一个数组low
把第一个数放进去
此时len=1
后面的数如果大于low[len]
len++
放到新的low[len]

如果小于等于low[len]
在前面找一个大于它的最小的数
顺便这里安利一下lower_bound()
用这个数来替换前面的数

二分太恶心了
不想找边界
lower_bound()是个好东西

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<climits>#include<string>#include<cstdlib>#include<map>#include<ctime>#define MAX 1000000007#define LL long longusing namespace std;int n,i,j,a[300005],h[300005],tot,ans1,ans2,low[300005],len,pos,up[300005];int part(int l,int r,int lend){    while(l<=r)    {        int mid=(l+r)/2;        if(up[mid]>=a[lend])        {            l=mid+1;        }        else        {            r=mid-1;        }               }       return l;}int main(){           n=1;    while(scanf("%d",&a[n])!=EOF)    {        n++;        }    n--;/////////////////////////////////////////////////////////////    up[1]=a[1];    len=1;    for(i=2;i<=n;i++)    {        if(a[i]<=up[len])        {            len++;            up[len]=a[i];        }        else        {            pos=part(1,len,i);            up[pos]=a[i];        }    }    ans1=len;//////////////////////////////////////////////////////////////    low[1]=a[1];    len=1;    for(i=2;i<=n;i++)    {        if(a[i]>low[len])        {            len++;            low[len]=a[i];        }        else        {            pos=lower_bound(low,low+len+1,a[i])-low;            low[pos]=a[i];        }    }    ans2=len;   ////////////////////////////////////////////////////////////////////    printf("%d\n%d",ans1,ans2);    return 0;} 
原创粉丝点击