題目連結:The Best Gift (CF 609B)
核心標籤:組合數學、頻率統計、複雜度優化
書店有 n 本書(n ≤ 2×10⁵),屬於 m 種流派(m ≤ 10),每種至少一本。Jack 要買不同流派的兩本書,求方案數。兩方案若至少一本書不同則視為不同。答案不超過 2×10⁹。
// 兩層迴圈檢查所有配對
for (i = 1; i < n; i++)
for (j = 0; j < i; j++)
if (books[i] != books[j]) ways++;
// n=2e5 時 2e10 次操作,必超時
總配對數 = C(n,2) = n(n-1)/2。
同流派配對數 = ΣC(cnt[i], 2),其中 cnt[i] 為第 i 種流派的書本數。
不同流派配對數 = 總配對數 - 同流派配對數。
更直觀的單趟掃描累加法:
int cnt[11] = {0};
for (i = 0; i < n; i++) {
scanf("%d", &x);
cnt[x]++;
}
long long ans = 0;
int remaining = n;
for (i = 1; i <= m; i++) {
remaining -= cnt[i]; // 扣除當前流派
ans += 1LL * cnt[i] * remaining; // 當前流派 × 其後所有其他流派
}
printf("%lld\n", ans);
時間 O(n + m),空間 O(m),m ≤ 10 極小,瞬間 AC。
| 輸入 | 流派分佈 | 計算過程 | 答案 |
|---|---|---|---|
4 3 | 流派1:2本, 流派2:1本, 流派3:1本 | 2×(1+1) + 1×1 = 5 | 5 |
7 4 | 各2本, 流派1:1本 | 2×5 + 2×3 + 2×1 + 1×0 = 18 | 18 |
m ≤ 10 這類小範圍值,陣列計數是 O(1) 存取的最佳結構n=2e5 時答案約 2e10,需 long long / __int64此題是「暴力→數學優化」的教科書級案例,同類思想廣泛應用於配對計數、逆序對、子陣列和等問題。