很好的一道題。
思路
由於 \(n\) 較小。
我們可以列舉位置 \((i,j)\) 統計逆序對。
由於每次交換 \((x,y)\) 只會影響與 \(x,y\) 有關的逆序對。
所以我們可以在修改的時候暴力修改。
但是這樣有一個問題。
就是我們統計總和的時候,其他項應該需要乘二。
我們可能可以想到一些技巧性的方法比如整體打標記,給特殊項除二。
考慮我們實際統計的是什麼。
是機率!
我們可以統計每一個逆序對出現的機率。
在最後面給答案乘上 \(2^m\) 就是期望。
這也是期望與機率的互轉。
如何 dp。
設 \(f1_{i,j}\) 表示 \(a_i<a_j\) 的機率,\(f2_{i,j}\) 表示 \(a_i>a_j\) 的機率。
轉移比較簡單,讀者可以自行思考。
時間複雜度:\(O(n(n+q))\)。
這道題其實有一個機率版本,CF258D。
Code
/*
! Though life is hard, I want it to be boiling.
! Created: 2024/04/10 09:10:38
*/
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
// #define int long long
#define mp(x, y) make_pair(x, y)
#define eb(...) emplace_back(__VA_ARGS__)
#define fro(i, x, y) for (int i = (x); i <= (y); i++)
#define pre(i, x, y) for (int i = (x); i >= (y); i--)
inline void JYFILE19();
typedef long long i64;
typedef pair<int, int> PII;
bool ST;
const int N = 3010;
const int mod = 1e9 + 7;
const int inv = 500000004;
i64 n, m, a[N], f1[N][N], f2[N][N];
signed main() {
JYFILE19();
cin >> n >> m;
fro(i, 1, n) cin >> a[i];
fro(i, 1, n) fro(j, i + 1, n) f1[i][j] = (a[i] < a[j]);
fro(i, 1, n) fro(j, i + 1, n) f2[i][j] = (a[i] > a[j]);
fro(i, 1, m) {
int l, r;
cin >> l >> r;
if (l > r) swap(l, r);
vector<int> fl1(n + 1);
vector<int> fr1(n + 1);
vector<int> fl2(n + 1);
vector<int> fr2(n + 1);
fro(j, 1, n) {
if (j == l) continue;
if (j < l) {
fl1[j] = f1[j][r], fl2[j] = f2[j][r];
} else if (j < r) {
fl1[j] = f2[j][r], fl2[j] = f1[j][r];
} else if (j > r) {
fl1[j] = f1[r][j], fl2[j] = f2[r][j];
}
}
fro(j, 1, n) {
if (j == r) continue;
if (j > r) {
fr1[j] = f1[l][j], fr2[j] = f2[l][j];
} else if (j > l) {
fr1[j] = f2[l][j], fr2[j] = f1[l][j];
} else if (j < l) {
fr1[j] = f1[j][l], fr2[j] = f2[j][l];
}
}
fl1[r] = f2[l][r], fl2[r] = f1[l][r];
fro(j, 1, n) {
if (j < r && j != l) f1[j][r] = (fr1[j] + f1[j][r]) % mod, f2[j][r] = (fr2[j] + f2[j][r]) % mod;
if (j > r) f1[r][j] = (fr1[j] + f1[r][j]) % mod, f2[r][j] = (fr2[j] + f2[r][j]) % mod;
if (j < l) f1[j][l] = (fl1[j] + f1[j][l]) % mod, f2[j][l] = (fl2[j] + f2[j][l]) % mod;
if (j > l && j != r) f1[l][j] = (fl1[j] + f1[l][j]) % mod, f2[l][j] = (fl2[j] + f2[l][j]) % mod;
}
f1[l][r] = (fl1[r] + f1[l][r]) % mod;
f2[l][r] = (fl2[r] + f2[l][r]) % mod;
}
int ans = 0;
fro(i, 1, n) fro(j, i + 1, n) (ans += f2[i][j]) %= mod;
cout << ans << "\n";
return 0;
}
bool ED;
inline void JYFILE19() {
// freopen("", "r", stdin);
// freopen("", "w", stdout);
srand(random_device{}());
ios::sync_with_stdio(0), cin.tie(0);
double MIB = fabs((&ED-&ST)/1048576.), LIM = 1024;
cerr << "MEMORY: " << MIB << endl, assert(MIB<=LIM);
}