题意翻译:给定一个数列 AAA,你可以选择两个正整数 l,rl,rl,r,并将 Al,Al+1,...,Ar−1,ArA_l,A_{l+1},...,A_{r-1},A_rAl ,Al+1 ,...,Ar−1 ,Ar 都变为它们的平均数,求操作后 AAA 数列的种数。
我们正着求种数太复杂了,考虑拿总数(即 N×(N+1)÷2N\times(N+1)\div 2N×(N+1)÷2)减去重复的情况数。
重复情况分为以下两种:
1. Aj,Aj+1,...,Ai−2,Ai−1A_j,A_{j+1},...,A_{i-2},A_{i-1}Aj ,Aj+1 ,...,Ai−2 ,Ai−1 的平均数恰好为 AiA_iAi 。
2. Ai+1,Ai+2,...,Aj−1,AjA_{i+1},A_{i+2},...,A_{j-1},A_{j}Ai+1 ,Ai+2 ,...,Aj−1 ,Aj 的平均数恰好为 AiA_iAi 。
情况 2 我想不出来怎么弄,所以就把 AAA 数列反转一下,求两次情况 1,最后加回重复减的。
注意到所有 AiA_iAi 均为正整数,所以如果情况重复,那么平均数也必定是正整数,且在 [1,30][1,30][1,30] 内。
我们可以创建数组 preprepre,使 pre[i][j]=∑k=1j(Ak−i)pre[i][j]=\sum_{k=1}^j (A_k-i)pre[i][j]=∑k=1j (Ak −i),这样如果 pre[i][j]=pre[i][k]pre[i][j]=pre[i][k]pre[i][j]=pre[i][k],就说明 Aj,Aj+1,Aj+2,...,Ak−1,AkA_j,A_{j+1},A_{j+2},...,A_{k-1},A_kAj ,Aj+1 ,Aj+2 ,...,Ak−1 ,Ak 的平均数为 iii。
于是操作 1 记录的就是如下的式子:
∑i=1N∑j=0i−1(pre[Ai][i]=pre[Ai][j])\sum_{i=1}^N \sum_{j=0}^{i-1} (pre[A_i][i]=pre[A_i][j]) i=1∑N j=0∑i−1 (pre[Ai ][i]=pre[Ai ][j])
接着我们想想这样会多减多少种情况。
显然,如果两个正整数 i,ji,ji,j 满足 Ai=AjA_i=A_jAi =Aj 且 Ai+1,Ai+2,..Aj−2,Aj−1A_{i+1},A_{i+2},..A_{j-2},A_{j-1}Ai+1 ,Ai+2 ,..Aj−2 ,Aj−1 的平均数也恰好为 AiA_iAi ,则这种情况会被减两次,需要加回来。
所以要加回来的总情况数就是:
∑i=1N∑j=1i−1(Ai=Aj 且 pre[Ai][i]=pre[Ai][j])\sum_{i=1}^N\sum_{j=1}^{i-1} (A_i=A_j\space且 \space pre[A_i][i]=pre[A_i][j]) i=1∑N j=1∑i−1 (Ai =Aj 且 pre[Ai ][i]=pre[Ai ][j])
代码如下:
时间复杂度 O(N×Ai+N2)O(N\times A_i+N^2)O(N×Ai +N2)。
这篇代码可以通过离散化(排序聚集相等元素)优化成 O(NlogN×Ai)O(N\log N\times A_i)O(NlogN×Ai ),请读者自行完成。