[NOIp2014提高组]解方程

思路:

系数的范围有$10^{10000}$,但是用高精度做显然不现实,因此可以考虑一个类似于“哈希”的做法,
对方程两边同时取模,如果取的模数足够多,正确率就很高了。
中间对多项式的计算可以使用$O(n)$的秦九韶算法。
然而,我的模数试了很多种都不能A,看了题解发现只要对$1000000007$一个数取模就AC了?

 1 #include<cstdio>
 2 #include<cctype>
 3 const long long mod=1000000007;
 4 inline long long getll() {
 5     bool sgn=false;
 6     char ch;
 7     while(!isdigit(ch=getchar())) if(ch=='-') sgn=true;
 8     long long x=ch^'0';
 9     while(isdigit(ch=getchar())) x=((((x<<2)+x)<<1)+(ch^'0'))%mod;
10     return sgn?-x:x;
11 }
12 const long long N=100,M=1000001;
13 long long n;
14 long long a[N];
15 long long ans[M]={0};
16 inline bool check(const long long x) {
17     long long sum=0;
18     for(long long i=n;i>=0;i--) {
19         sum=(sum*x+a[i])%mod;
20     }
21     return sum==0;
22 }
23 int main() {
24     n=getll();
25     long long m=getll();
26     for(long long i=0;i<=n;i++) a[i]=getll();
27     for(long long i=1;i<=m;i++) {
28         if(check(i)) ans[++ans[0]]=i;
29     }
30     for(long long i=0;i<=ans[0];i++) printf("%lld\n",ans[i]);
31     return 0;
32 }

试了很多个模数都没能AC的代码:

 1 #include<tuple>
 2 #include<cstdio>
 3 #include<cctype>
 4 inline int getint() {
 5     char ch;
 6     while(!isdigit(ch=getchar()));
 7     int x=ch^'0';
 8     while(isdigit(ch=getchar())) x=((((x<<2)+x)<<1)+(ch^'0'));
 9     return x;
10 }
11 const int mod_size=5;
12 const int mod[mod_size]={19260817,19260817,19260817,19260817,19260817};
13 inline std::tuple<int,int,int,int,int> gettuple() {
14     bool sgn=false;
15     char ch;
16     while(!isdigit(ch=getchar())) if(ch=='-') sgn=true;
17     int x[mod_size];
18     for(int i=0;i<mod_size;i++) x[i]=ch^'0';
19     while(isdigit(ch=getchar())) {
20         for(int i=0;i<mod_size;i++) {
21             x[i]=((((x[i]<<2)+x[i])<<1)+(ch^'0'))%mod[i];
22         }
23     }
24     return sgn?std::make_tuple(mod[0]-x[0],mod[1]-x[1],mod[2]-x[2],mod[3]-x[3],mod[4]-x[4]):std::make_tuple(x[0],x[1],x[2],x[3],x[4]);
25 }
26 const int N=100,M=1000001;
27 int n;
28 int a[mod_size][N];
29 int ans[M]={0};
30 inline bool check(const int x) {
31     int sum[mod_size];
32     for(int i=n;i>=0;i--) {
33         for(int j=0;j<mod_size;j++) {
34             sum[j]=(sum[j]*x%mod[j]+a[j][i])%mod[j];
35         }
36     }
37     bool ret=true;
38     for(int i=0;i<mod_size;i++) ret=ret&&!sum[i];
39     return ret;
40 }
41 int main() {
42     n=getint();
43     int m=getint();
44     for(int i=0;i<=n;i++) {
45         std::tuple<int,int,int,int,int> p=gettuple();
46         a[0][i]=std::get<0>(p);
47         a[1][i]=std::get<1>(p);
48         a[2][i]=std::get<2>(p);
49         a[3][i]=std::get<3>(p);
50         a[4][i]=std::get<4>(p);
51     }
52     for(int i=1;i<=m;i++) if(check(i)) ans[++ans[0]]=i;
53     for(int i=0;i<=ans[0];i++) printf("%d\n",ans[i]);
54     return 0;
55 }
View Code

 

posted @ 2017-08-15 15:28  skylee03  阅读(175)  评论(0编辑  收藏  举报