This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define int long long
#define ll long long
#define all(lpv) lpv.begin(), lpv.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6 + 5;
const int oo = 1e16;
const int mod = 1e6 + 3;
int n, a[N], m, zero;
void add(int &x,int y){
if(x == -1) x = y;
else x = min(x, y);
}
int bit[N];
void update(int i,int val){
for(; i <= n; i += i & -i) bit[i] += val;
}
int get(int i){
int ret = 0;
for(; i; i -= i & -i) ret += bit[i];
return ret;
}
namespace AC{
pair<int,int> save[2][N];
int g[2][2];
vector<int> vr[N];
void solve(){
int pre = 0, nx = 1;
g[pre][0] = 0;
g[pre][1] = -1;
g[nx][0] = g[nx][1] = -1;
int sum = 0;
for(int i = 1; i <= n; i ++) if(a[i] != 0){
vr[abs(a[i])].push_back(i);
}
int ans = -1;
for(int val = m; val >= 1; val --){
// cerr << val << " r\n";
// for(auto i : vr[val]) cerr << i << " ";
// cerr << " h\n";
for(int t = 0; t <= 1; t ++) if(g[pre][t] != -1){
int ble = t, bri = (sum - t) % 2;
// cerr << val << " " << t << " " << g[pre][t] << " " << ble << " " << bri << " start\n";
deque<int> col[2], rev[2];
for(auto i : vr[val]){
if(i & 1){
if(a[i] > 0) col[0].push_back(i);
else col[1].push_back(i);
}else{
if(a[i] > 0) col[1].push_back(i);
else col[0].push_back(i);
}
if((n - i + 1) & 1){
if(a[i] > 0) rev[0].push_back(i);
else rev[1].push_back(i);
}else{
if(a[i] > 0) rev[1].push_back(i);
else rev[0].push_back(i);
}
}
int le = 0, ri = 0;
int tmp = (int)vr[val].size();
int ret = 0;
while(le < tmp){
int nxt = ((ble + le + 1) & 1);
if(col[nxt].empty()) break;
le++;
int x = col[nxt].front();
ret += x - 1 - get(x - 1);
update(x, 1);
if((n - x + 1) & 1){
if(a[x] > 0) rev[0].pop_front();
else rev[1].pop_front();
}else{
if(a[x] > 0) rev[1].pop_front();
else rev[0].pop_front();
}
save[0][le] = {nxt, x};
col[nxt].pop_front();
}
// cerr << le << " " << ret << " h\n";
while(ri < tmp - le){
int nxt = (((bri + ri + 1) & 1) ^ 1);
if(rev[nxt].empty()) break;
ri++;
int x = rev[nxt].back();
ret += n - x - (get(n) - get(x));
update(x, 1);
save[1][ri] = {nxt, x};
rev[nxt].pop_back();
}
while(le >= 0){
if(le + ri == tmp) add(g[nx][(ble + le) % 2], ret + g[pre][t]);
if(!le) break;
int nxt, x; tie(nxt, x) = save[0][le];
col[nxt].push_front(x);
update(x, -1);
ret -= x - 1 - get(x - 1);
if((n - x + 1) & 1){
if(a[x] > 0) rev[0].push_front(x);
else rev[1].push_front(x);
}else{
if(a[x] > 0) rev[1].push_front(x);
else rev[0].push_front(x);
}
le--;
while(ri < tmp - le){
int _right = (((bri + ri + 1) & 1) ^ 1);
if(rev[_right].empty()) break;
int pos = rev[_right].back();
ri++;
ret += (n - pos - (get(n) - get(pos)));
update(pos, 1);
save[1][ri] = {nxt, pos};
rev[_right].pop_back();
}
}
while(ri > 0){
int nxt, x; tie(nxt, x) = save[1][ri];
update(x, -1);
ri--;
}
g[pre][t] = -1;
}
sum += (int)vr[val].size();
for(auto i : vr[val]) update(i, 1);
if(g[nx][0] == -1 && g[nx][1] == -1){
cout << -1;
return;
}
swap(pre, nx);
}
if(g[pre][0] != -1) add(ans, g[pre][0]);
if(g[pre][1] != -1) add(ans, g[pre][1]);
cout << ans;
}
}
signed main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define task "v"
if(fopen(task ".inp","r")){
freopen(task ".inp","r",stdin);
freopen(task ".out","w",stdout);
}
cin >> n;
vector<int> rrh;
for(int i = 1; i <= n; i ++){
cin >> a[i];
zero += (a[i] == 0);
if(a[i] != 0) rrh.push_back(abs(a[i]));
}
sort(all(rrh)); rrh.resize(unique(all(rrh)) - rrh.begin());
m = (int)rrh.size();
for(int i = 1; i <= n; i ++){
if(a[i] == 0) continue;
if(a[i] < 0) a[i] = -(lower_bound(all(rrh), abs(a[i])) - rrh.begin() + 1);
else a[i] = lower_bound(all(rrh), abs(a[i])) - rrh.begin() + 1;
}
AC :: solve();
}
/*
5
0 -1 -1 0 1
*/
Compilation message (stderr)
Main.cpp: In function 'int main()':
Main.cpp:171:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
171 | freopen(task ".inp","r",stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:172:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
172 | freopen(task ".out","w",stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |