https://codeforces.com/contest/1598/problem/C
定義一個數組 \(\{a_i\}\)的 \(mean\) 為 \(\frac{\sum{a_i}}{n}\),給定一個數組,問有多少個有序對 \((i,j), i\leq j\),使得去掉 \(a_i, a_j\)后數組的 \(mean' = mean\)
這題題面有毒,一開始理解成了數組的 \(gcd\) 不變,而且除法是數學除法,帶余數的那種
在理解了正確題意下來考慮這道題:
假設原數組的和為 \(sum\) ,原數組的 \(mean\) 為 \(k\),那么一定有 \(nk = sum\)。
現在去掉兩個數,數組的和變為 \((n-2)k\),因此被減去的兩數之和為 \(2sum/n\),顯然如果 \(2sum \mod n != 0\) 則不存在解。
接下來就可以枚舉 \(a_i+a_j\) 的數對個數,題解說這是一個經典問題,可以用 map 保存每個值出現了多少次,則對於值 \(a,\ 2sum/n-a\) 對答案的貢獻即為 \(cnt[a]*\ cnt[2sum/n-a]\), 如果 \(a,\ 2sum/n-a\) 兩值相等,那么答案需要--,最后再去重除2即可。
點擊查看代碼
#include <bits/stdc++.h>
using namespace std;
using DB = double;
using ll = long long;
using PII = pair<int, int>;
const int N = 2e5 + 10;
const ll INF = 1e18;
#define endl '\n'
int n = 2, m;
int a[N];
int st[6][1005], cntt[6];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--) {
cin >> n;
ll sum = 0;
map<int, int> cnt;
for (int i = 0, x; i < n; i++) {
cin >> a[i];
sum += a[i];
cnt[a[i]]++;
}
if (2 * sum % n != 0) {
cout << 0 << endl;
continue;
}
ll res = 2 * sum / n, ans = 0;
for (int i = 0; i < n; i++) {
int x = a[i];
int y = res - x;
ans += cnt[y];
if (x == y)
ans--;
}
cout << ans / 2 << endl;
}
return 0;
}