APCS 109/10 實作題第四題 題解
2020-10-21 19:10:48 by
題目敘述
給一個長度 \(2n\) 的數列,其中 \(1 \sim n\) 各出現恰兩次。對於每一組相同的數,我們去計算在它們之間有多少數字比它們小,求所有組的這個數字的總和。
輸入格式
第一行有一個整數 \(n\)
第二行有 \(2n\) 個 \(1 \sim n\) 的整數
\(1 \le n \le 100000\)
輸出格式
印出答案一個數字
範例輸入
4
4 2 1 3 2 1 4 3
範例輸出
8
子任務
- 20% : \(n \le 1000\)
- 40% : \(n \le 40000\)
- 40% : 無限制
題解
\(O(N \log N)\) 樹狀數組或分治法
C++ 參考解答
#include <iostream>
using namespace std;
bool F[100001];
int B[100001];
int main() {
cin.tie(NULL);
ios_base::sync_with_stdio(false);
int N;
cin >> N;
long long ans = 0;
for (int i = 0; i < N * 2; i++) {
int x;
cin >> x;
int cnt = 0;
for (int y = x - 1; y > 0; y -= y & -y) cnt += B[y];
for (int y = x; y <= N; y += y & -y) B[y]++;
if (F[x]) {
ans += cnt;
} else {
F[x] = true;
ans -= cnt;
}
}
cout << ans << endl;
return 0;
}
[題解] [APCS] [APCS 109/10]