Subject to the effect
Gives a \ (n-\) arranged, when the \ (a [i] = i \) then \ (I \) is a fixed point, now you can choose a range flip it, after seeking the maximum inversion fixed point (can only choose an interval, flipping once ).
analysis
For the first exchange \ ((i, j) \ ) there are only three circumstances:
- \ (I \) is not in its upper position, after resetting the exchange. ( \ (J \) empathy)
- \ (i \) is not in his place, after the exchange is still in.
- \ (i \) turned in his place, after exchanging gone.
The latter two with prefixes and statistics on the line, the first one, we find \ ((i, a [i ]) \) in the center of the \ ((i, a [i ]) \) hanging in the center and then sorted by length, we only deal with the elements have reset the exchange, other exchanges will be able to use the prefix and statistics.
Code
The code a bit ugly, forgive me.
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100007;
int n, ret = -0x3f3f3f3f, sum[N], a[N];
struct note { int l, r, len; };
vector<note> lis1[N], lis2[N];
int cmp(note a, note b) { return a.len < b.len; }
void doit1()
{
for (int i = 1, p, q; i <= n; i++)
{
p = i, q = a[i];
if (p > q) swap(p, q);
if ((q - p) % 2 == 0) lis1[(p + q) / 2].push_back((note){p, q, q - p + 1});
}
for (int i = 1; i <= n; i++)
{
sort(lis1[i].begin(), lis1[i].end(), cmp);
int sz = lis1[i].size(), s = 0;
for (int j = 0, lasl = i, lasr = i; j < sz; j++)
{
if (lis1[i][j].len == 1) { ret = max(ret, s); continue; }
if (lis1[i][j].l < lasl) s -= sum[lasl - 1] - sum[lis1[i][j].l];
if (lasr < lis1[i][j].r) s -= sum[lis1[i][j].r - 1] - sum[lasr];
if (j < sz - 1)
{
if (lis1[i][j].len == lis1[i][j + 1].len) s += 2, ++j;
else s += 1;
}
else s += 1;
lasl = lis1[i][j].l, lasr = lis1[i][j].r;
ret = max(ret, s);
}
}
}
void doit2()
{
for (int i = 1, p, q; i <= n; i++)
{
p = i, q = a[i];
if (p > q) swap(p, q);
if ((q - p) % 2 == 1) lis2[(p + q) / 2].push_back((note){p, q, q - p + 1});
}
for (int i = 1; i <= n; i++)
{
sort(lis2[i].begin(), lis2[i].end(), cmp);
int sz = lis2[i].size(), s = 0;
for (int j = 0, lasl = i + 1, lasr = i; j < sz; j++)
{
if (lis2[i][j].l < lasl) s -= sum[lasl - 1] - sum[lis2[i][j].l];
if (lasr < lis2[i][j].r) s -= sum[lis2[i][j].r - 1] - sum[lasr];
if (j < sz - 1)
{
if (lis2[i][j].len == lis2[i][j + 1].len) s += 2, ++j;
else s += 1;
}
else s += 1;
lasl = lis2[i][j].l, lasr = lis2[i][j].r;
ret = max(ret, s);
}
}
}
int main()
{
//freopen("rotate.in", "r", stdin);
//freopen("rotate.out", "w", stdout);
//freopen("in", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), sum[i] = sum[i - 1] + (i == a[i]);
doit1();
doit2();
printf("%d\n", sum[n] + ret);
return 0;
}