一起來解讀LIS吧!

~hsm~發表於2019-03-07

lis加強版

title

描述 Description
有N個整數,輸出這N個整數的最長上升序列、最長下降序列、最長不上升序列和最長不下降序列。
輸入格式 Input Format
第一行,僅有一個數N。 N<=700000
第二行,有N個整數。 -109<=每個數<=109
輸出格式 Output Format
第一行,輸出最長上升序列長度。
第二行,輸出最長下降序列長度。
第三行,輸出最長不上升序列長度。
第四行,輸出最長不下降序列長度。
樣例輸入 Sample Input
10
1 3 0 8 6 2 3 1 4 2
樣例輸出 Sample Output
4
4
4
4
時間限制 Time Limitation
1s
註釋 Hint
資料生成由 zqc,heaonan,zhouhang 等人對拍而成。
來源 Source
經典例題

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=7e5+10,inf=0x3f3f3f3f;
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1,ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
long long ans1,ans2,ans3,ans4,a[maxn],b[maxn],c[maxn],d[maxn],e[maxn];
struct cmp
{
	bool operator() (int a,int b)
	{
		return a>b;
	}
};
int main()
{
	int n;read(n);
	for (int i=1;i<=n;++i)
		read(a[i]);
	ans1=ans2=ans3=ans4=1;
	b[1]=e[1]=c[1]=d[1]=a[1];
	for (int i=2;i<=n;++i)
	{
		if (a[i]>b[ans1]) b[++ans1]=a[i];
		else if (a[i]<b[ans1]) b[lower_bound(b+1,b+ans1+1,a[i])-b]=a[i];

		if (a[i]<c[ans2]) c[++ans2]=a[i];
		else if (a[i]>c[ans2]) c[lower_bound(c+1,c+ans2+1,a[i],cmp())-c]=a[i];

		if (a[i]<=d[ans3]) d[++ans3]=a[i];
		else if (a[i]>d[ans3]) d[upper_bound(d+1,d+ans3+1,a[i],cmp())-d]=a[i];

		if (a[i]>=e[ans4]) e[++ans4]=a[i];
		else if (a[i]<e[ans4]) e[upper_bound(e+1,e+ans4+1,a[i])-e]=a[i];
	}
	printf("%lld\n%lld\n%lld\n%lld\n",ans1,ans2,ans3,ans4);
	return 0;
}

相關文章