[ABC262D] I Hate Non-integer Number

Problem Statement

You are given a sequence of positive integers $A=(a_1,\ldots,a_N)$ of length $N$.
There are $(2^N-1)$ ways to choose one or more terms of $A$. How many of them have an integer-valued average? Find the count modulo $998244353$.

Constraints

  • $1 \leq N \leq 100$
  • $1 \leq a_i \leq 10^9$
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

$N$
$a_1$ $\ldots$ $a_N$

Output

Print the answer.


Sample Input 1

3
2 6 2

Sample Output 1

6

For each way to choose terms of $A$, the average is obtained as follows:

  • If just $a_1$ is chosen, the average is $\frac{a_1}{1}=\frac{2}{1} = 2$, which is an integer.

  • If just $a_2$ is chosen, the average is $\frac{a_2}{1}=\frac{6}{1} = 6$, which is an integer.

  • If just $a_3$ is chosen, the average is $\frac{a_3}{1}=\frac{2}{1} = 2$, which is an integer.

  • If $a_1$ and $a_2$ are chosen, the average is $\frac{a_1+a_2}{2}=\frac{2+6}{2} = 4$, which is an integer.

  • If $a_1$ and $a_3$ are chosen, the average is $\frac{a_1+a_3}{2}=\frac{2+2}{2} = 2$, which is an integer.

  • If $a_2$ and $a_3$ are chosen, the average is $\frac{a_2+a_3}{2}=\frac{6+2}{2} = 4$, which is an integer.

  • If $a_1$, $a_2$, and $a_3$ are chosen, the average is $\frac{a_1+a_2+a_3}{3}=\frac{2+6+2}{3} = \frac{10}{3}$, which is not an integer.

Therefore, $6$ ways satisfy the condition.


Sample Input 2

5
5 5 5 5 5
首先枚举选了 $i$ 个数,那么这 $i$ 个数的和一定是 $i$ 的倍数。所以在模 $i$ 的意义下dp。统计 a 中有多少个数模 $i$ 余 $j$,枚举使用了那些余数,设 $dp_{j,k,l}$ 表示用了前 $j$ 个余数,目前的所有和模 $i$ 余 $k$,选了 $l$ 个数。则枚举余数为 $j$ 选多少个,然后转移就行了。
#include<bits/stdc++.h>
const int N=105,P=998244353;
int n,a[N],c[N],dp[N][N][N],ans,f[N][N];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	f[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		f[i][0]=f[i][i]=1;
		for(int j=1;j<i;j++)
			f[i][j]=(f[i-1][j]+f[i-1][j-1])%P;
	}
	for(int i=1;i<=n;i++)
	{
		memset(c,0,sizeof(c));
		for(int j=1;j<=n;j++)
			c[a[j]%i]++;
		memset(dp,0,sizeof(dp));
		dp[0][0][0]=1;
		for(int j=0;j<i;j++)//枚举用到那个余数
		{
			for(int k=0;k<=c[j];k++)//用几个
			{
				for(int y=0;y<i;y++)
				{
					for(int w=k;w<=i;w++)
					{
						dp[j+1][y][w]+=1LL*dp[j][(y-k*j%i+i)%i][w-k]*f[c[j]][k]%P,dp[j+1][y][w]%=P;
					}
				}
			}
		}
		ans+=dp[i][0][i],ans%=P;
//		printf("%d\n",dp[1][0][2]);
	}
	printf("%d",ans);
}
posted @ 2022-09-10 09:38  灰鲭鲨  阅读(30)  评论(0编辑  收藏  举报