题解 CF1598C Delete Two Elements
\[\text{题目大意}
\]
\(\quad\)从 \(n\) 个数中删除两个数 \(a_i,a_j(i<j)\),且满足平均数不变,问有多少种删法?
\[\text{思路}
\]
\(\quad\)设原数列的平均数为 \(k\),且删除 \(a_i,a_j\) 后平均数不变,可得:
\[\frac{a_i+a_j}{2}=k
\]
\(\quad\)又 \(\because a_i,a_j\) 为整数,\(\therefore k\times 2\) 为整数,若 \(k\) 不符合这条件就直接输出 \(0\)。
\(\quad\)显然开个桶计数即可,即:
\[ \left\{
\begin{aligned}
& ans+=num[x]\times num[y],& ,x+y=k\times2\\
& ans+=num[x]\times (num[x]-1)/2& ,x=k
\end{aligned}
\right.
\]
\(\quad\)依次统计答案即可,时间复杂度 \(O(n\log n)\) (使用 \(map\) 作为桶),记得每次统计完要清零,防止多次统计。
\(\quad\)这里还有另一种思路,可以直接排序,然后两个指针从一头一尾向中间跑,每次处理一段相同的值,或者用结构体,一维存大小,一维存数量,再排序,时间复杂度也是 \(O(n\log n)\)。
注意:开 long long,多组数据清空数组。
const int N=2e5+5;
int T,n,a[N],k,ans;
map<int,int>b;
signed main()
{
T=read();
while(T--){
n=read();a[0]=0;ans=0;
for(re i=1;i<=n;i++)a[i]=read(),a[0]+=a[i],b[a[i]]++;
if(a[0]*2%n!=0){for(re i=1;i<=n;i++)b[a[i]]=0;puts("0");continue;}
k=a[0]*2/n;
for(re i=1;i<=n;i++)
{
int x=a[i],y=k-x;
if(b[x]==0)continue;
if(x==y){ans+=(long long)(b[x]-1)*b[x]/2;b[x]=0;}
else ans+=(long long)b[x]*b[y],b[x]=b[y]=0;
if(b[x])b[x]=0;
}
print(ans);putchar('\n');
}
return 0;
}