[BZOJ3751][NOIP2014]解方程(数学相关+乱搞)

Posted Kaiser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ3751][NOIP2014]解方程(数学相关+乱搞)相关的知识,希望对你有一定的参考价值。

题目描述

已知多项式方程:

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

 

题解:

  考试的时候取模数选的多还大无语了,然后总觉得不对。

  后来看了题解发现,我那样被严重卡常数。

  只需要取几个较小的模数,然后将式子左边取模,然后讲1-p(表示模数)

  每个模拟一次就是pn复杂度,然后看哪几个不为0,说明绝对不行,那么其倍数

  也不行,多选几个模数就可以了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 
 7 const int N=101;
 8 const int L=10010;
 9 const int M=1000010;
10 const int TOT=4;
11 
12 int n,m,ans;
13 int p[TOT+1],a[N],len[N];
14 bool flg[M];
15 char s[N][L];
16 
17 void make_list()
18 {
19     p[1]=22349;
20     p[2]=22367;
21     p[3]=22369;
22     p[4]=17389;
23 }
24 int main()
25 {
26     make_list();
27     scanf("%d%d",&n,&m);
28     for(int i=0;i<=n;i++)
29         scanf("%s",s[i]);
30     for(int i=0;i<=n;i++)
31         len[i]=strlen(s[i]);
32     for(int i=1;i<=TOT;i++)
33     {
34         for(int j=0;j<=n;j++)
35         {
36             int flag=(s[j][0]==-?1:0);
37             a[j]=0;
38             for(int k=flag;k<len[j];k++)
39                 a[j]=(a[j]*10+s[j][k]-0)%p[i];
40             if(flag) a[j]=-a[j];
41         }//每个系数先取模 
42         for(int j=1;j<=p[i];j++)
43         {
44             int tmp=0;
45             for(int k=n;k>=0;k--)
46                 tmp=(tmp*j+a[k])%p[i];
47             if(tmp)//表示不行 
48             for(int k=0;j+k*p[i]<=m;k++)
49                 flg[j+k*p[i]]=1;//其倍数也不行 
50         }
51     }
52     for(int i=1;i<=m;i++)
53         if(!flg[i]) ans++;
54     printf("%d\n",ans);
55     for(int i=1;i<=m;i++)
56         if(!flg[i]) printf("%d\n",i);
57 }

 

以上是关于[BZOJ3751][NOIP2014]解方程(数学相关+乱搞)的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3751] [NOIP2014] 解方程 (数学)

[BZOJ 3751][NOIP2014]解方程(哈希)

[BZOJ3751][NOIP2014]解方程(数学相关+乱搞)

hashBZOJ3751-[NOIP2014]解方程

noip2014解方程解题报告

[NOIP2014提高组]解方程