1. 程式人生 > >Consecutive Subsequence CodeForces - 977F (map優化DP)·

Consecutive Subsequence CodeForces - 977F (map優化DP)·

nta ssis put scanf std ans tar 長度 equal

You are given an integer array of length nn.

You have to choose some subsequence of this array of maximum length such that this subsequence forms a increasing sequence of consecutive integers. In other words the required sequence should be equal to [x,x+1,,x+k1][x,x+1,…,x+k−1] for some value

xx and length kk.

Subsequence of an array can be obtained by erasing some (possibly zero) elements from the array. You can erase any elements, not necessarily going successively. The remaining elements preserve their order. For example, for the array [5,3,1,2,4][5,3,1,2,4] the following arrays are subsequences:

[3][3], [5,3,1,2,4][5,3,1,2,4], [5,1,4][5,1,4], but the array [1,3][1,3] is not.

Input

The first line of the input containing integer number nn (1n21051≤n≤2⋅105) — the length of the array. The second line of the input containing nn integer numbers a1,a2,,ana1,a2,…,an (

1ai1091≤ai≤109) — the array itself.

Output

On the first line print kk — the maximum length of the subsequence of the given array that forms an increasing sequence of consecutive integers.

On the second line print the sequence of the indices of the any maximum length subsequence of the given array that forms an increasing sequence of consecutive integers.

Examples

Input
7
3 3 4 7 5 6 8
Output
4
2 3 5 6
Input
6
1 3 5 2 4 6
Output
2
1 4
Input
4
10 9 8 7
Output
1
1
Input
9
6 7 8 3 4 5 9 10 11
Output
6
1 2 3 7 8 9

Note

All valid answers for the first example (as sequences of indices):

  • [1,3,5,6][1,3,5,6]
  • [2,3,5,6][2,3,5,6]

All valid answers for the second example:

  • [1,4][1,4]
  • [2,5][2,5]
  • [3,6][3,6]

All valid answers for the third example:

  • [1][1]
  • [2][2]
  • [3][3]
  • [4][4]

All valid answers for the fourth example:

  • [1,2,3,7,8,9]

題意:

給定一個含有N個整數的數組,求出最大的長度len,使之數組中可以不連續的子數組時嚴格遞增1的數組,並要求輸出這個子數組的每一個元素的下標。

思路:

類似最長上升子序列的問題,但這裏的要求是每一次必須遞增1,即數值是連續+1 的。

那麽我們可以考慮,對於訪問到的每一個a[i]時,以a[i]為最後一個數值的子數組的長度dp[a[i]] = dp[a[i]-1] + 1 (即轉移方程)

因為a[i]的範圍是1~1e9,所以dp不能開數組,而要開map<int,int> dp;

找出子數組的每一個下標。

我用的是一個比較簡單的方法。

因為每一次連續遞增1的性質,我們只需記錄最大的ans值的dp[a[i]] 的下標值i,

那麽這個遞增的子數組的初始值就是a[i]-ans+1

然後我們O(N) 掃一遍數組,以此輸出數組中的那些連續的數值的下標即可。

細節見ACODE:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), ‘\0‘, sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
int a[maxn];
map<int,int> m;
map<int,int> pre;
int main()
{
    //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
    //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
    gbtb;
    cin>>n;
    repd(i,1,n)
    {
        cin>>a[i];
    }
    int ans=0;
    int id;
    repd(i,1,n)
    {
        m[a[i]]=m[a[i]-1]+1;
        if(m[a[i]]>ans)
        {
            ans = m[a[i]];
            id=i;
        }
        ans = max(ans,m[a[i]]);
    }
    int num=a[id]-ans+1;
    std::vector<int> v;
    int cnt=0;
    repd(i,1,n)
    {
        if(a[i]==num)
        {
            v.pb(i);
            num++;
            cnt++;
        }
    }
    cout<<max(cnt,ans)<<endl;
    for(auto x:v)
    {
        cout<<x<<" ";
    }
    cout<<endl;
    
    
    
    
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch ==   || ch == \n);
    if (ch == -) {
        *p = -(getchar() - 0);
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 - ch + 0;
        }
    }
    else {
        *p = ch - 0;
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 + ch - 0;
        }
    }
}

Consecutive Subsequence CodeForces - 977F (map優化DP)·