题目描述 Description

输入描述 Input Description

输入文件名为equation.in。

输入共n+2行。

第一行包含2个整数n、m,每两个整数之间用一个空格隔开。

接下来的n+1行每行包含一个整数,依次为a0,a1,a2,……,an

 

输出描述 Output Description

输出文件名为equation.out。

第一行输出方程在[1, m]内的整数解的个数。

接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。

 

 

样例输入 Sample Input

equation.in

equation.out

2 10

1

-2

1

 

1

1

equation.in

equation.out

2 10

-3

1

 

2

1

2

 

样例输出 Sample Output

equation.in

equation.out

2 10

1

3

2

 

0

数据范围及提示 Data Size & Hint

http://codevs.cn/problem/3732/

30% 我们只需要枚举1到m并且计算f(i)是否为0即可

50% 与30%思路相同,只是改为高精度(建议使用重载运算符)

70% 取5,6个较大的模数,将ai输入的同时进行取模,如果都为0就记为答案

100% 对于f(i)的值取模p时,f(i)=f(i%p)所以不需要枚举到m,只要到每个质数-1,即可,而较大的数的值只需找对应的5个值查看即可。

#include<cstdio>
#include<cstring>
int n,pr[5]={11261,19997,22877,21893,14843},qm[105][5],jl[1000005];
bool vis[5][30005];
char c[10005];
int f(int a,int b,int c)
{
    if(a==n) return qm[n][b];
    return (qm[a][b]+f(a+1,b,c)*c%pr[b])%pr[b];
}
int main()
{
    int m,ans=0;
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;++i)
    {
        scanf("%s",c);
        int l=strlen(c),f=c[0]=='-'?1:0;
        for(int j=0;j<5;++j)
        {
            for(int k=f;k<l;++k)
                qm[i][j]=(qm[i][j]*10+c[k]-'0')%pr[j];
            if(f) qm[i][j]=-qm[i][j];
        }
    }
    for(int i=0;i<5;++i)
        for(int j=0;j<pr[i];++j)
            if(f(0,i,j)) vis[i][j]=1;
    for(int i=1;i<=m;++i)
    {
        bool sf=1;
        for(int j=0;j<5;++j)
            if(vis[j][i%pr[j]]) sf=0;
        if(sf) jl[ans++]=i;
    }
    printf("%d\n",ans);
    for(int i=0;i<ans;++i) printf("%d\n",jl[i]);
    return 0;
}