描述
已知多项式方程:
a0+a1x+a2x2+...+anxn=0a0+a1x+a2x2+...+anxn=0
求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。
格式
输入格式
输入共 n+2 行。
第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。
接下来的 n+1 行每行包含一个整数,依次为a0,a1,a2,...,ana0,a1,a2,...,an
。
输出格式
第一行输出方程在[1, m]内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。
限制
对于 30%的数据,0 < n ≤ 2, |ai||ai|
≤ 100,anan
≠ 0, m ≤ 100;
对于 50%的数据,0 < n ≤ 100, |ai||ai|
≤ 1010010100
,anan
≠ 0,m ≤ 100;
对于 70%的数据,0 < n ≤ 100, |ai||ai|
≤ 10100001010000
,anan
≠ 0,m ≤ 10000;
对于 100%的数据,0 < n ≤ 100, |ai||ai|
≤ 10100001010000
,anan
≠ 0,m ≤ 1000000。
来源
NOIP2014 提高组 Day2
初看本题,知道要取模一个素数但是有两个地方没考虑
1一个素数不够用,可能要出错,用5个素数就差不多了,这五个素数可以比较小10^4级就可以了
2根据题意如果f(x)=0,那么f(x+p)=0,后面的就不用算了
AC代码
1 #include<cstdio> 2 #include<iostream> 3 #define M 1000002 4 #define N 102 5 using namespace std; 6 int n,m; 7 int ans[M]; 8 int a[N][5]; 9 int t[205][5]; 10 int c[25000][5]; 11 int p[5]={10007,23333,11119,11777,11177}; 12 int cal(int y) 13 { 14 int tmp=0; 15 for(int i=0;i<=n;i++) 16 tmp=(tmp+a[i][y]*t[i][y])%p[y]; 17 if(tmp<0)//减法取余要注意可能减到负数 18 tmp+=p[y]; 19 return tmp; 20 } 21 bool check(int mm) 22 { 23 for(int i=0;i<5;i++) 24 if(c[mm%p[i]][i]!=0) 25 return false; 26 return true; 27 } 28 int main() 29 { 30 cin>>n>>m; 31 for(int i=0;i<=n;i++)//读大系数 32 { 33 char ai[10005]; 34 scanf("%s",ai); 35 for(int k=0;k<5;k++) 36 { 37 int factor=0; 38 int j=0; 39 if(ai[0]=='-')j++; 40 for(;;j++) 41 { 42 if(ai[j]<='9'&&ai[j]>='0') 43 factor=(factor*10+ai[j]-'0')%p[k]; 44 else break; 45 } 46 if(ai[0]=='-') 47 factor*=-1; 48 a[i][k]=factor; 49 } 50 } 51 for(int i=0;i<5;i++) 52 for(int j=1;j<=p[i];j++) 53 { 54 t[0][i]=1;//第一个系数为a0*x^0 55 for(int k=1;k<=n;k++)t[k][i]=(t[k-1][i]*j)%p[i]; 56 c[j][i]=cal(i); 57 } 58 for(int i=1;i<=m;i++) 59 if(check(i)) 60 ans[++ans[0]]=i; 61 cout<<ans[0]<<endl; 62 for(int i=1;i<=ans[0];i++) 63 printf("%d\n",ans[i]); 64 return 0; 65 }