模拟 最长上升子串

来源:互联网 发布:pnp网络摄像机软件 编辑:程序博客网 时间:2024/05/23 17:21
   

问题 A: 最长上升子串

时间限制: 2 Sec  内存限制: 64 MB

题目描述

输入

6
7 2 3 1 5 6

输出

5

提示

     出题人说这是联赛DAY1的难度。。。第一眼看觉得挺难。。。再看一眼。。。发现好水,

     联考时就AC了,他们还有树状数组优化出O(N*log(N)^2)效率就去讲台上装逼的。。实在没忍住,给他们讲了讲我O(N)效率的大模拟。。。

     不扯淡了,因为必须要选连续的区间,而已经是严格上升的子串不会被修改。所以处理出每一个严格上升的区间,去考虑是否修改其两端点。如果这个区间就一个点,特殊考虑就行。

     

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define inf 1000000000#define N 300000using namespace std;int read(){    int sum=0,f=1;char x=getchar();    while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}    while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}    return sum*f;}int n,a[N+5],b[N+5],cnt,ans=0;struct node{    int l,r,size;} t[N+5];int main(){    n=read();    a[0]=inf;a[n+1]=-inf;    for(int i=1;i<=n;i++)    {        a[i]=read();        if(a[i]<=a[i-1])        {            cnt++;            b[i]=cnt;            t[cnt].l=i;            t[cnt].size++;            t[cnt-1].r=i-1;        }        else        {            b[i]=cnt;            t[cnt].size++;        }    }    t[cnt].r=n;t[cnt+1].l=n+1;    for(int i=1;i<=cnt;i++)    {        if(t[i].l==t[i].r)        {            if(a[t[i+1].l]-a[t[i-1].r]>1)               ans=max(ans,t[i-1].size+t[i+1].size+1);            else               ans=max(ans,max(t[i-1].size,t[i+1].size)+1);        }        else        {            int l=t[i].l,r=t[i].r;            if(a[l+1]-a[l-1]>1)               ans=max(ans,t[i-1].size+t[i].size);            if(a[r+1]-a[r-1]>1)               ans=max(ans,t[i].size+t[i+1].size);            if(t[i].size!=n)ans=max(ans,t[i].size+1);            else ans=n;        }    }    cout<<ans;}

原创粉丝点击