BZOJ_P1318 [SPOJ744] Longest Permutation(单调栈)

来源:互联网 发布:python mobi 下载 编辑:程序博客网 时间:2024/06/06 09:03

BZOJ传送门

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 414 Solved: 250
[Submit][Status][Discuss]
Description
给你一个序列A含有n个正整数(1<=Ai<=n)。A的子集形式类如Au, Au+1 … , Av (1<=u<=v<=n),即必须是连续的。我们感兴趣的是一种子集,它含有元素包括1,2,…k。(k是子集的大小)。 你的任务是找到这种类型的最长的子集。

Input
第一行,一个数n,表示序列A的长度 第二行,n个数,第I个数表示元素Ai

Output
一个数,表示可选子集的长度

Sample Input
5
4 1 2 3 2

Sample Output
4

HINT
你可以选得子集从A1开始到A4,这个子集长度为4,包含了1,2,3,4)
1<=n<=100010

Source

跟上篇辣题一毛一样,除了数据范围大了10,然而这并没有什么卵用

#include<cstdio>#include<iostream>using namespace std;#define N 100015#define INF 0x7fffffffint stk[N],a[N],tp[N],n,s,ans,l,r;inline int in(int x=0,char ch=getchar()){while(ch>'9'||ch<'0') ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}inline void Check(int l,int r,int ll){if(ll>r) return;if(a[ll]>ans&&r-l+1>=a[ll]) ans=a[ll];}int main(){    n=in();stk[r+1]=INF;    for(int i=1;i<=n;i++){        a[i]=in();        s=max(tp[a[i]]+1,s);        while(tp[a[i]]>=stk[l]) Check(stk[l]+1,i-1,stk[l+1]),l++;        while(l<=r&&a[i]>=a[stk[r]]) Check(max(s,stk[r-1]+1),i-1,stk[r]),r--;        tp[a[i]]=i,stk[++r]=i,stk[r+1]=INF,Check(s,i,stk[l]);    }    while(l<=r) Check(stk[l]+1,n,stk[l+1]),l++;    printf("%d\n",ans);}
0 0