Submission #1014983

#TimeUsernameProblemLanguageResultExecution timeMemory
1014983ThunnusLongest beautiful sequence (IZhO17_subsequence)C++17
100 / 100
3440 ms233920 KiB
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int i64
#define vi vector<int>
#define vvi vector<vi>
#define vb vector<bool>
#define pii pair<int, int>
#define fi first
#define se second
#define sz(x) (int)(x).size()

const int B = 10;

struct State{
    int len, end;
};

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    vvi bc(1 << B, vi(1 << B));
    for(int i = 0; i < (1 << B); i++)
        for(int j = 0; j < (1 << B); j++)
            bc[i][j] = __builtin_popcount(i & j);
    int n, ans = 1, best_i = 0;
    cin >> n;
    vi a(n), k(n);
    for(int &i : a)
        cin >> i;
    for(int &i : k)
        cin >> i;
    
    vi prev(n);
    iota(prev.begin(), prev.end(), 0);
    vector<vector<vector<State>>> dp(1 << B, vector<vector<State>>(1 << B, vector<State>(B + 1)));
    for(int i = 0; i < n; i++){
        int l = a[i] >> B, r = a[i] % (1 << B), lbs = 1;
        for(int j = 0; j < (1 << B); j++){ //  enumerate all possibilities for l(prev_num)
            // here, we use the fact that bc[x][y] = bc[l(x)][l(y)] + bc[r(x)][r(y)], or bc[r(x)][r(y)] = bc[x][y] - bc[l(x)][l(y)]
            int needed = k[i] - bc[j][l]; // required value of bc[r(x)][r(y)]
            if(needed < 0 || needed > B) continue;
            if(dp[j][r][needed].len + 1 > lbs){
                lbs = dp[j][r][needed].len + 1;
                prev[i] = dp[j][r][needed].end;
            }   
        }
        if(lbs > ans){
            ans = lbs;
            best_i = i;
        }

        for(int j = 0; j < (1 << B); j++){ // update all answers a[i] affects
            State &new_state = dp[l][j][bc[r][j]];
            if(lbs > new_state.len){
                new_state.len = lbs;
                new_state.end = i;
            }
        }
    }

    cout << ans << "\n";
    vi res;
    while(prev[best_i] != best_i){
        res.emplace_back(best_i + 1);
        best_i = prev[best_i];
    }
    res.emplace_back(best_i + 1);
    reverse(res.begin(), res.end());
    for(int i : res){
        cout << i << " ";
    }
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...