思路没问题 反转一段并不会影响剩余段的逆序数 只会影响该段的逆序数
那么只需要考虑原始序列的逆序对的奇偶性和反转之后序列的逆序对的奇偶性
翻转一段序列会使原先非逆序对的变成逆序对 原先是逆序对的变成非逆序对
而逆序对的个数加上非逆序对的个数为所有可能的二元组 那么就是C(n, 2)
只需考虑C(n, 2)的奇偶
- 是奇数 则反转后奇偶性一定反转
- 是偶数 则反转后奇偶性一定不变
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;
int a[N], tmp[N], n, m;
ll merge_sort(int l, int r) {
if (l >= r) return 0;
int mid = (l + r) >> 1;
ll cnt = merge_sort(l, mid) + merge_sort(mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) tmp[k ++] = a[i ++];
else {
tmp[k ++] = a[j ++];
cnt += mid - i + 1;
}
}
while (i <= mid) tmp[k ++] = a[i ++];
while (j <= r) tmp[k ++] = a[j ++];
for (i = l, j = 0;i <= r; ++ i, ++ j) a[i] = tmp[j];
return cnt;
}
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n;
for (int i = 1;i <= n; ++ i) cin >> a[i];
ll res = merge_sort(1, n);
cin >> m;
//求出原序列的逆序对的奇偶性
int t = (res % 2 == 1 ? 1 : 0);
while (m--) {
ll l, r;cin >> l >> r;
ll len = r - l + 1;
ll sum = (len - 1) * len / 2;
//如果二元组数目为奇数 则t += 1
if (sum % 2) t += 1;
if (t % 2) puts("dislike");
else puts("like");
}
}