[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
-2
1
输出样例#1:
1
1
输入样例#2:
2 10
2
-3
1
输出样例#2:
2
1
2
输入样例#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 }

 

posted @ 2016-11-18 18:17  SilverNebula  阅读(398)  评论(0编辑  收藏  举报
AmazingCounters.com