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;
}
posted @ 2016-05-10 15:32  invoid  阅读(166)  评论(0编辑  收藏  举报