#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ul;
typedef unsigned long long ull;
#define MASK(i) (1ULL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
#define ALL(v) (v).begin(), (v).end()
ll gcd(ll a, ll b){return __gcd(a, b);}
ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}
ll LASTBIT(ll mask){return (mask) & (-mask);}
int pop_cnt(ll mask){return __builtin_popcountll(mask);}
int ctz(ull mask){return __builtin_ctzll(mask);}
int logOf(ull mask){return 63 - __builtin_clzll(mask);}
// mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
mt19937_64 rng(1);
ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);}
template <class T1, class T2>
bool maximize(T1 &a, T2 b){
if (a < b) {a = b; return true;}
return false;
}
template <class T1, class T2>
bool minimize(T1 &a, T2 b){
if (a > b) {a = b; return true;}
return false;
}
template <class T>
void printArr(T the_array_itself, string separator = " ", string finish = "\n", ostream &out = cout){
for(auto item: the_array_itself) out << item << separator;
out << finish;
}
template <class T>
void remove_dup(vector<T> &a){
sort(ALL(a));
a.resize(unique(ALL(a)) - a.begin());
}
const ll INF = 1e18 + 69;
struct SegmentTree{
int n;
vector<pair<ll, int>> a;
SegmentTree(int _n){
n = _n;
a.resize(n * 2 + 2, make_pair(-INF, 0));
for(int i = 1; i <= n; ++i) a[i + n] = make_pair(-INF, i);
for(int i = n; i >= 1; --i) a[i] = max(a[i * 2], a[i * 2 + 1]);
}
void update(int i, ll v){
i += n; a[i].first = v;
while(i > 1){
i >>= 1;
a[i] = max(a[i * 2], a[i * 2 + 1]);
}
}
pair<ll, int> get(int l, int r){
l += n; r += n + 1;
pair<ll, int> ans = make_pair(-INF, 0);
while(l < r){
if (l & 1) maximize(ans, a[l++]);
if (r & 1) maximize(ans, a[--r]);
l >>= 1; r >>= 1;
}
return ans;
}
};
void answer(int e){
cout << e << " ";
}
ll convert(ll i, ll j, ll k){
return (i << 40) + (j << 20) + k;
}
array<int, 3> convert_back(ll x){
return {{x / MASK(40) % MASK(20), x / MASK(20) % MASK(20), x % MASK(20)}};
}
void solve(){
int n; cin >> n;
int m; cin >> m;
vector<int> a(m);
for(int i = 0; i < m; ++i) cin >> a[i];
vector<pair<int,ll>> b;
b.reserve(m);
int e = 0;
for(int i = 0; i < m; ){
if (a[i] != e){
if (b.empty() || b.back().first != a[i]) b.push_back({a[i], 1});
else b.back().second++;
++i;
}
else{
if (a[i+1] == e){
int k = a[i+2];
if (b.empty() || b.back().first != e) b.push_back({e, k+1});
else b.back().second += k+1;
}
else{
if (a[i+2] == 0){
e = a[i+1];
}
else{
int k = a[i+2];
if (b.empty() || b.back().first != a[i+1]) b.push_back({a[i+1], k+3});
else b.back().second += k+3;
}
}
i += 3;
}
}
SegmentTree st(n), rst(n);
st.update(1, 0); rst.update(1, 0);
for(int i = 2; i <= n; ++i) {
st.update(i, 3);
rst.update(i, -3);
}
ll tot = 0;
vector<ll> awesome;
const int M = 2e6;
awesome.reserve(M);
for(int i = 2; i <= n; ++i) awesome.push_back(convert(0, 1, i));
int t = 0;
for(pair<int, ll> i: b){
i.first++; t++;
ll cost1 = 0, cost2 = 0;
ll tmp = i.second;
cost1 = (tmp / (n+2)) * 3;
tmp %= n+2;
cost1 += min(tmp, 3);
tmp = i.second;
cost2 = (tmp / n) * 3;
tmp %= n;
if (tmp)
cost2 += 3;
tot += cost1;
pair<ll, int> val = st.get(i.first, i.first);
st.update(i.first, val.first + cost2 - cost1);
rst.update(i.first, -(val.first + cost2 - cost1));
pair<ll, int> mi = rst.get(1, n);
mi.first *= -1;
while(true){
pair<ll, int> ma = st.get(1, n);
if (ma.first > mi.first + 3){
st.update(ma.second, mi.first + 3);
rst.update(ma.second, -(mi.first+3));
awesome.push_back(convert(t, mi.second, ma.second));
}
else break;
}
if (awesome.size() >= M) assert(false);
}
pair<ll, int> mi = rst.get(1, n);
mi.first *= -1;
cout << mi.first + tot << "\n";
t = b.size();
e = mi.second;
vector<int> color(t+1, -1);
while(t > 0){
array<int, 3> cur = {{-1, -1, -1}};
while(awesome.size()){
array<int, 3> bacc = convert_back(awesome.back());
if (bacc[0] < t && bacc[2] == e) {
cur = bacc;
awesome.pop_back();
break;
}
awesome.pop_back();
}
if (cur[0] < 0) break;
t = cur[0];
color[t] = e;
e = cur[1];
}
e = 1;
for(int i = 0; i < (int) b.size(); ++i){
if (color[i] != -1){
answer(e-1);
answer(color[i]-1);
answer(0);
e = color[i];
}
pair<ll, ll> it = b[i];
it.first++;
if (it.first == e){
while(it.second >= n){
answer(e-1);
answer(e-1);
answer(n-1);
it.second -= n;
}
if (it.second){
answer(e-1);
answer(e-1);
answer(it.second-1);
}
}
else{
while(it.second >= n + 2){
answer(e-1);
answer(it.first-1);
answer(n-1);
it.second -= n+2;
}
if (it.second <= 3){
while(it.second--) answer(it.first-1);
}
else{
answer(e-1);
answer(it.first-1);
answer(it.second-3);
}
}
}
cout << "\n";
}
int main(void){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
clock_t start = clock();
solve();
cerr << "Time elapsed: " << clock() - start << "ms!\n";
return 0;
}
Compilation message (stderr)
rle.cpp: In function 'std::array<int, 3> convert_back(ll)':
rle.cpp:92:27: warning: narrowing conversion of '((((long long unsigned int)x) / (1 << 40)) % (1 << 20))' from 'long long unsigned int' to 'int' [-Wnarrowing]
92 | return {{x / MASK(40) % MASK(20), x / MASK(20) % MASK(20), x % MASK(20)}};
| ^
rle.cpp:92:52: warning: narrowing conversion of '((((long long unsigned int)x) / (1 << 20)) % (1 << 20))' from 'long long unsigned int' to 'int' [-Wnarrowing]
92 | return {{x / MASK(40) % MASK(20), x / MASK(20) % MASK(20), x % MASK(20)}};
| ^
rle.cpp:92:66: warning: narrowing conversion of '(((long long unsigned int)x) % (1 << 20))' from 'long long unsigned int' to 'int' [-Wnarrowing]
92 | return {{x / MASK(40) % MASK(20), x / MASK(20) % MASK(20), x % MASK(20)}};
| ^| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |