首页 > 代码库 > [NOIP2014] 提高组 洛谷P2312 解方程

[NOIP2014] 提高组 洛谷P2312 解方程

 

题目描述

已知多项式方程:

a0+a1x+a2x^2+..+anx^n=0

求这个方程在[1, m ] 内的整数解(n 和m 均为正整数)

输入输出格式

输入格式:

 

输入文件名为equation .in。

输入共n + 2 行。

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

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

 

输出格式:

 

输出文件名为equation .out 。

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

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

 

输入输出样例

输入样例#1:
2 10 1-21
输出样例#1:
11
输入样例#2:
2 102-31
输出样例#2:
212
输入样例#3:
2 10 1  3  2   
输出样例#3:
0

说明

30%:0<n<=2,|ai|<=100,an!=0,m<100

50%:0<n<=100,|ai|<=10^100,an!=0,m<100

70%:0<n<=100,|ai|<=10^10000,an!=0,m<10000

100%:0<n<=100,|ai|<=10^10000,an!=0,m<1000000

 

直接计算无疑是不可能做到的。

将每一项的系数都模一个质数,若一个数是方程的解,那么在模的意义下它也是方程的解(但反过来不一定)。

为了解决这个“不一定”的问题,多选几个质数,若一个数在不同模的意义下都是方程的解,那么它有极大的几率就是原方程的解了。

↑如果素数选得不好,这题还是会WA。

↑所以这是道拼RP的题。

 

 1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mod[8]={0,13,7901,3947,131,6977,22877,49997};10 char s[105][1000010];11 int n,m;12 int num[9][120];13 bool solve(int od,int x){14     int i,j;15     long long tmp=0;16     long long pw=1;17     for(i=0;i<=n;++i){18 //        printf("%d %d\n",num[od][i],pw);19         if(s[i][0]==-) tmp=(tmp-pw*num[od][i])%mod[od];20         else tmp=(tmp+pw*num[od][i])%mod[od];21         pw=pw*x%mod[od];22     }23     while(tmp<0) tmp+=mod[od];24     if(!tmp)return true;25     return false;26 }27 int res[1000010];28 int ans[1000010],act=0;29 int main(){30     int i,j,k;31     scanf("%d%d",&n,&m);32     for(i=0;i<=n;++i)33         scanf("%s",s[i]);34     int len[101];35     for(i=0;i<=n;++i)len[i]=strlen(s[i]);36     for(k=1;k<=7;++k)37         for(i=0;i<=n;++i){38             for(j=0;j<len[i];++j){39                 if(s[i][j]==-)continue;40                 num[k][i]=num[k][i]*10+s[i][j]-0;41                 num[k][i]%=mod[k];42             }43         }44     for(k=1;k<=7;++k)45         for(i=0;i<mod[k] && i<=m;++i){46             if(!solve(k,i))continue;47             ++res[i];48             for(j=i+mod[k];j<=m;j+=mod[k]){49 //                if(solve(k,j))50                 res[j]++;51             }52         }53     for(i=1;i<=m;++i)54         if(res[i]==7)ans[++act]=i;55     printf("%d\n",act);56     for(i=1;i<=act;++i)printf("%d\n",ans[i]);57     return 0;58 }

 

[NOIP2014] 提高组 洛谷P2312 解方程