AT4363 [ARC102D] Revenge of BBuBBBlesort
https://www.luogu.com.cn/problem/AT4363
发现奇数位和偶数位的逆序对个数互不影响
- 奇数位上的数一定不会换到偶数位上
- 每次交换,只会让奇数位或偶数位其中一个的逆序对个数-1,让总逆序对数-3
所以
总
逆
序
对
个
数
=
3
(
奇
数
位
逆
序
对
个
数
+
偶
数
位
逆
序
对
个
数
)
总逆序对个数=3(奇数位逆序对个数+偶数位逆序对个数)
总逆序对个数=3(奇数位逆序对个数+偶数位逆序对个数)
然后不难证明这是充要的
代码求3遍逆序对即可
code:
#include<bits/stdc++.h>
#define ll long long
#define N 300050
#define lowbit(x) (x & -x)
using namespace std;
int t[N], n, a[N];
void update(int x, int y) {
for(; x <= n; x += lowbit(x)) t[x] += y;
}
int query(int x) {
int ret = 0;
for(; x; x -= lowbit(x)) ret += t[x];
return ret;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++) if((a[i] & 1) != (i & 1)) {
printf("No"); return 0;
}
ll s0 = 0, s1 = 0, s2 = 0;
for(int i = 1; i <= n; i ++) {
update(a[i], 1);
s2 += i - query(a[i]);
}
for(int i = 0; i <= n; i ++) t[i] = 0;
for(int i = 1; i <= n; i += 2) {
update(a[i], 1);
s1 += (i + 1) / 2 - query(a[i]);
}
for(int i = 0; i <= n; i ++) t[i] = 0;
for(int i = 2; i <= n; i += 2) {
update(a[i], 1);
s0 += i / 2 - query(a[i]);
}
if(3 * (s0 + s1) == s2) printf("Yes");
else printf("No");
return 0;
}