題解 CF1598C Delete Two Elements
阿新 • • 發佈:2021-10-25
\[\text{題目大意}
\] 依次統計答案即可,時間複雜度 \(O(n\log n)\) (使用 \(map\) 作為桶),記得每次統計完要清零,防止多次統計。
\(\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\)
\(\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; }