codevs3732 解方程
%%%。设f(x)=a0+a1x+a2x^2+ … + anx^n.求f(x)=0的x。
数据范围很大,高精度只能骗分。
运用类似hash的思想。 如果这个等式mod p 还成立(p为质数)那它很可能就是成立。
多取几个质数(大质数更优)就可以几乎确定了。(70分)
100分时m很大,不能都算出来。
仔细分析,如果在模p时f(x)!=0,则f(x+p)肯定也不是解。这样一来只需枚举从1到p的数即可确定所有的数是否能为解。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 100000 + 10; const int maxm = 1000000 + 10; const long long p[]={11261,19997,22877,21893,14843,17851}; long long a[110][10]; long long f[maxn][10]; int n,m,cnt; char s[maxn]; bool able[maxm]; int res[maxm]; long long calc (long long i,int j) { long long sum=a[0][j]; long long t=1; i=i%p[j]; for(int k=1;k<=n;k++) { t=t*i%p[j]; sum=(sum+a[k][j]*t)%p[j]; } return sum; } int main() { bool sgn; scanf("%d%d",&n,&m); for(int i=0,l;i<=n;i++) { scanf("%s",s); l=strlen(s); sgn=0; for(int j=0;j<l;j++) { if(s[j]=='-') { sgn=1; continue; } for(int k=0;k<6;k++) a[i][k]=(a[i][k]*10+s[j]-'0')%p[k]; } if(sgn) for(int k=0;k<6;k++) a[i][k]=p[k]-a[i][k]; } for(int j=0;j<6;j++) for(int i=1;i<=p[j];i++) f[i][j]=calc(i,j); memset(able,1,sizeof(able)); for(int j=0;j<6;j++) for(int i=1;i<=m;i++) if(f[i%p[j]][j] != 0) able[i]=0; for(int i=1;i<=m;i++) if(able[i]) res[++cnt]=i; printf("%d\n",cnt); for(int i=1;i<=cnt;i++) printf("%d\n",res[i]); return 0; }