[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 ] 内的一个整数解。
输入输出样例
说明
对于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] 解方程 (数学)