JZOJ6288 [] [] A group NOIP improve rotator segment

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;
}

Guess you like

Origin www.cnblogs.com/zjlcnblogs/p/11328305.html