Codeforces 414C Mashmokh and Reverse Operation

题意:给你2^n个数,每次操作将其分成2^k份,对于每一份内部的数进行翻转,每次操作完后输出操作后的2^n个数的逆序数。

解法:2^n个数,可以联想到建立一棵二叉树的东西,比如  2,1,4,3就可以建成下面这样

                                                    [2,1,4,3]                        level 2

                                                   /               \

                                              [2,1]              [4,3]                  level 1

                                           /        \              /     \

                                        [2]         [1]        [4]    [3]              level 0

然后算某个区间的逆序数的时候[2,1,4,3]实际上就是算[2,1],[4,3]的逆序数再加上[2,1],[4,3]之间的逆序数,思路和归并排序是一样的。

然后我们看下每次翻转,假如我们分成2^k份,我们会发现,对于level k+1层以上的逆序数是不会改变的,但是level k~level 0的逆序数对会翻转,我们只需要知道level k~level 0各个区间翻转后的逆序数就可以了。 

所以做法就有点类似于归并求逆序数,对于每个结点,记inv[0]为不翻转时的逆序数,inv[1]为翻转的时候的逆序数,然后我们记sum[k][0]和sum[k][1] 为该层所有结点的inv[0]的和 以及inv[1]的和。 然后每次操作就是将 sum[k~0]的0,1值交换,然后逆序数就是sum[n~0][0]的和。

#pragma warning(disable:4996)

#include<iostream>

#include<cstring>

#include<string>

#include<cstdio>

#include<algorithm>

#include<vector>

#include<cmath>

#define ll long long

#define maxn 2000000

using namespace std;



ll a[maxn];

int n;



ll sum[25][2];



void build(int dep,int L, int R)

{

	if (dep == 0){

		sum[dep][0] = sum[dep][1] = 0; return;

	}

	int M = (L + R) >> 1;

	build(dep - 1, L, M); build(dep - 1, M + 1, R);

	for (int i = L; i <= M; i++){

		sum[dep][1] += a+R+1-upper_bound(a + M + 1, a + R + 1, a[i]);

		sum[dep][0] += lower_bound(a + M + 1, a + R+1, a[i]) - (a + M + 1);

	}

	sort(a + L, a + R + 1);

};



int main()

{

	while (cin >> n)

	{

		memset(sum, 0, sizeof(sum));

		int tot = 1 << n;

		for (int i = 1; i <= tot; i++){

			scanf("%I64d", a + i);

		}

		build(n, 1, tot);

		int m, q;

		cin >> m;

		for (int i = 0; i < m; i++){

			scanf("%d", &q);

			for (int j = q; j >= 0; j--){

				swap(sum[j][0], sum[j][1]);

			}

			ll ans = 0;

			for (int j = n; j >= 0; j--){

				ans += (ll)sum[j][0];

			}

			printf("%I64d\n", ans);

		}

	}

	return 0;

}

 

你可能感兴趣的:(codeforces)