POJ 3471 Integral Roots(素数、因数)

题目链接:http://poj.org/problem?id=3471

题意:给出一个多项式f(x),求f(x)=0所有的整数根。

 

思路:由于求的是f(x)的整数根,设它的整数根分别为x1,x2……,则f(x)可以写成这种形式:

f(x)=a*(x-x1)*(x-x2)*(x-x3)*……

f(x)最后的常数为0,则有根0,f(x)可以除掉x,因此总能化成上式。设f(x)最后的常数项为p,我们发现:

p=x1*x2*x3*……,所以只要这样求解即可:

(1)求出p的所有因数组成集合Q;

(2)枚举Q的某个元素xi,若可以使得f(xi)=0,则xi为一个解,f(x)=f(x)/(x-xi);

(3)在Q中继续(2),直到找不到一个xi,结束。

 

那么接下来就是对于一个给定的xi,怎么计算f(xi)是不是等于0?霍纳法则,我以前只知道但是从来没用过:

f(x)=(((x+a)*x+b)*x+c)……就是这个意思,然后找个素数,每次对该素数取模即可。。。

 

 #include <iostream>

 #include <cstdio>

 #include <cstring>

 #include <algorithm>

 #define int64 __int64

 using namespace std;

 

 int64 MOD[]={13251349,13251361,13251367,

              13251373,13251377,13251383};

              

              

 int64 prime[60000],isprime[60000],cnt;

 

 

 void init()

 {

     int64 i,j;

     cnt=0;

     for(i=2;i<60000;i++)

     {

         if(!isprime[i]) prime[++cnt]=i;

         for(j=1;j<=cnt&&prime[j]*i<60000;j++)

         {

             isprime[prime[j]*i]=1;

             if(i%prime[j]==0) break;

         }

     }

 }

 

 struct node

 {

     int64 prime,num;

 };

 

 node a[100];

 int64 n,aNum,factor[10000],factorNum;

 int64 coef[105];

 

 

 int64 ABS(int64 x)

 {

     if(x<0) return -x;

     return x;

 }

 

 void DFS(int64 x,int dep)

 {

     int64 i;

     if(dep==aNum+1)

     {

         factor[factorNum++]=x;

     }

     else

     {

         for(i=0;i<=a[dep].num;i++)

         {

             DFS(x,dep+1);

             x=x*a[dep].prime;

         }

     }

 }

 

 void cal(int64 p)

 {

     aNum=0;

     int64 i;

     for(i=1;i<=cnt;i++) if(p%prime[i]==0)

     {

         aNum++;

         a[aNum].prime=prime[i];

         a[aNum].num=0;

         while(p%prime[i]==0)

         {

             a[aNum].num++;

             p/=prime[i];

         }

     }

     if(p>1)

     {

         aNum++;

         a[aNum].prime=p;

         a[aNum].num=1;

     }

     factorNum=0;

     DFS(1,1);

 }

 

 int OK(int64 a)

 {

     int64 r,b,i,j;

     for(i=0;i<6;i++)

     {

         r=0;

         b=a%MOD[i];

         for(j=n;j>=0;j--) r=(r*b+coef[j])%MOD[i];

         if(r) return 0;

     }

     return 1;

 }

 

 int64 ans[10005],ansNum;

 

 int main()

 {

     init();

     while(scanf("%d",&n)!=-1)

     {

         int64 i,j,k,t,r,u;

         for(i=n-1;i>=0;i--) scanf("%I64d",&coef[i]);

         coef[n]=1;

         ansNum=0;

         k=0;

         factorNum=0;

         while(n)

         {

             if(coef[0]==0)

             {

                 ans[ansNum++]=0;

                 for(i=0;i<n;i++) coef[i]=coef[i+1];

                 n--;

             }

             else

             {

                 if(!factorNum) cal(ABS(coef[0]));

                 t=0;

                 for(i=k;i<factorNum;i++) if(coef[0]%factor[i]==0)

                 {

                     if(OK(factor[i]))

                     {

                         t=factor[i];

                         k=i;

                         break;

                     }

                     if(OK(-factor[i]))

                     {

                         t=-factor[i];

                         k=i;

                         break;

                     }

                 }

                 if(!t) break;

                 ans[ansNum++]=t;

                 r=0;

                 for(i=n;i>=0;i--)

                 {

                     u=r*t+coef[i];

                     coef[i]=r;

                     r=u;

                 }

                 n--;

             }

         }

         sort(ans,ans+ansNum);

         printf("%I64d\n",ansNum);

         for(i=0;i<ansNum;i++) printf("%I64d\n",ans[i]);

     }

     return 0;

 }

 

  

 

你可能感兴趣的:(root)