【简要题面】给定一个含n个正整数的序列。选取任意个不重复的子序列,将其按顺序拼接起来,保证有a[i+1]=a[i]+1。求最长子序列,含有spj,n<=2e5
【分析】
一个结论,同样的一个数字:比如说是3,后面的3一定不比前面的3差。所以直接用map记录每个数字最后出现的位置,然后dp值从上一个位置转移过来就可以了。
【code】
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=2e5+1000;
int kase,n;
int a[maxn];
int f[maxn],opt[maxn];
map<int,int>mp;
inline void read(int &x){
x=0;char tmp=getchar();int fl=1;
while(tmp<'0'||tmp>'9'){if(tmp=='-')fl=-fl;tmp=getchar();}
while(tmp>='0'&&tmp<='9') x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
x=x*fl;
}
void prt(int x){
if(!x) return ;
prt(opt[x]);
printf("%d ",x);
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
cin>>kase>>n;
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++){
f[i]=f[mp[a[i]-1]]+1,opt[i]=mp[a[i]-1];
mp[a[i]]=i;
}
int pos=0;
for(int i=1;i<=n;i++)
if(f[i]>=f[pos]) pos=i;
cout<<f[pos]<<endl;
prt(pos);
return 0;
}