题目传送门
题意: 给你一个数组,找出其中最长的+1上升子序列,输出长度并且输出一条合法的位置。
input
7
3 3 4 7 5 6 8
output
4
2 3 5 6
比如样例,我们可以找到3 4 5 6这个+1上升子序列,他们分别在2 3 5 6的位置。
思路: 我们用一个map<int,int>ma 来记录如果以这个数为结尾能获得的最大长度,我们输入一个x时,我们就看,如果ma[x-1]+1<ma[x],就不修改,不然ma[x]=ma[x-1]+1,表示长度+1,,我们把ma[i]的最大值存下来,这个最大值就是长度,i就是子序列的结尾值,在输入数的时候不断更新,就可以获得一个最后结果,获得这个结尾值pre之后,我们还知道子序列的长度len。因为我们找到的结尾值是pre,长度为len,那么一定有一条合法的路径,是从pre-len+1到pre的,遍历输出就可以。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int eps=1e-6;
typedef long long ll;
typedef unsigned long long ull;
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
#define null NULL
int a[N];
signed main()
{
IOS;
int n;
cin>>n;
map<int,int>ma;int maxx=-1,x=-1;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(ma[a[i]-1]+1>ma[a[i]])
{
ma[a[i]]=ma[a[i]-1]+1;
}
if(maxx<ma[a[i]])
{
maxx=ma[a[i]];
x=a[i];
}
}
cout<<maxx<<endl;
int f=x-maxx+1;
for(int i=1;i<=n;i++)
{
if(a[i]==f)
{
cout<<i<<' ';
f++;
}
}
}