一道简单分块题,题目要求的是逆序对数量,那么对于每一次交换位置\(l,r(l \le r)\)的操作,我们只需要判断区间\((L,R)\)中大于与小于两个端点的数字个数即可,可以考虑将每个块中进行排序再二分达到快速查询,时间复杂度为\(O(n\sqrt{n}\log{n})\)
具体见代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 2e5 + 500;
int len, num[N], block[N], gt[N], L[N], R[N];
long long ans = 0;
long long work(int x, int k)
{
int l = L[k], r = R[k], res = R[k] + 1;
while (l <= r)
{
int mid = (l + r) >> 1;
if (block[mid] > x)
res = mid, r = mid - 1;
else
l = mid + 1;
}
return R[k] - res + 1;
}
void update(int l, int r)
{
if (gt[l] == gt[r])//直接暴力枚举
{
for (int i = l + 1; i < r; i++)
{
if (num[r] > num[i])
ans++;
else if (num[r] < num[i])
ans--;
if (num[l] < num[i])
ans++;
else if (num[l] > num[i])
ans--;
}
if (num[l] > num[r])
ans--;
else if (num[l] < num[r])
ans++;
swap(num[l], num[r]);
}
else
{
int i = l, j = r;
i++, j--;
while (gt[i] == gt[l])
{
if (num[r] > num[i])
ans++;
else if (num[r] < num[i])
ans--;
if (num[l] < num[i])
ans++;
else if (num[l] > num[i])
ans--;
i++;
}
while (gt[j] == gt[r])
{
if (num[r] > num[j])
ans++;
else if (num[r] < num[j])
ans--;
if (num[l] < num[j])
ans++;
else if (num[l] > num[j])
ans--;
j--;
}
for (int k = gt[i]; k <= gt[j]; k++)
{
ans += work(num[l], k);
ans -= len - work(num[l], k);
ans += len - work(num[r], k);
ans -= work(num[r], k);
}//二分找个数
if (num[l] > num[r])
ans--;
else if (num[l] < num[r])
ans++;
swap(num[l], num[r]);
for (int k = L[gt[r]]; k <= R[gt[r]]; k++)
block[k] = num[k];
for (int k = L[gt[l]]; k <= R[gt[l]]; k++)
block[k] = num[k];
sort(block + L[gt[l]], block + R[gt[l]] + 1);
sort(block + L[gt[r]], block + R[gt[r]] + 1);//更行块中的数值
}
}
int main()
{
int n, k;
scanf("%d%d", &n, &k);
len = sqrt(n);
for (int i = 1; i <= n; i++)
gt[i] = (i - 1) / len + 1, block[i] = i, num[i] = i;
for (int i = 1; i <= gt[n]; i++)
{
L[i] = (i - 1) * len + 1, R[i] = i * len;
sort(block + L[i], block + R[i] + 1);
}//预处理区间端点
while (k--)
{
int l, r;
scanf("%d%d", &l, &r);
if (l > r)
swap(l, r);
update(l, r);//进行更新
printf("%lld\n", ans);
}
return 0;
}
题解 CF785E 【Anton and Permutation】
原文:https://www.cnblogs.com/A2484337545/p/14358778.html