HDU4569/2013年长沙赛区Special equations

来源:互联网 发布:身边有关大数据的例子 编辑:程序博客网 时间:2024/05/16 04:58

Description

Let f(x) = anxn+ ...+ a1x+ a0,in which ai (0 <= i <=n)are all known integers. We call f(x)º 0 (modm)congruence equation. Ifm is acomposite, we can factor m intopowers of primes and solve every such single equation after which we merge themusing the Chinese Reminder Theorem. In this problem, you are asked to solve amuch simpler version of such equations, withm to be prime's square.

 

Input

The first line is the number of equationsT,T<=50.

Then comes T lines, each line startswith an integerdeg (1<=deg<=4), meaning that f(x)'s degreeisdeg. Then followsdeg integers, representing antoa0 (0 < abs(an) <= 100; abs(ai)<= 10000 whendeg>= 3, otherwise abs(ai) <= 100000000,i<n). The last integer is primepri (pri<=10000).

Remember, your task is to solve f(x)º 0 (modpri*pri)

 

Output

For each equation f(x) º 0 (mod pri*pri),first output the case number, then output anyone ofx if there are manyxfitting the equation, else output "No solution!"

 

Sample Input

4

2 1 1 -5 7

1 5 -2995 9929

2 1 -96255532 8930 9811

4 14 5458 7754 4946 -2210 9601

 

Sample Output

Case #1: Nosolution!

Case #2: 599

Case #3: 96255626

Case #4: No solution!

容易看出,若x0是同余方程

f(x)º 0 (modpa)                      (1)

的解,则它必是方程

f(x)º 0 (modpa- 1)                     (2)

的解,因此,必有与x0相应的方程(2)的某个解x1,使

x0ºx1 (modpa- 1)x0 = x1+pa- 1t0

此处,t0是某个适当的整数。

这提示我们:可以从方程(2)的解中去求方程(1)的解。于是,现在的问题是,对于方程(2)的每个解x1,是否必有方程(1)的解x0与之对应?若有,如何去确定它?

定理 p是素数,a³ 2是整数,f(x) = anxn+L+a1x+a0是整系数多项式,又设x1是同余方程(2)的一个解。以f¢(x)表示f(x)的导函数。

(f¢(x1)0 (mod p),则存在整数t,使得

x =x1+pa- 1t                       (3)

是同余方程(1)的解。

(f¢(x1)º 0 (modp),并且f(x1)º 0 (mod pa),则对于t = 01, 2, L, p - 1,式(3)中的x都是方程(1)的解。

证明 我们来说明,如何确定式(3)中的t,使x1+pa- 1t满足同余方程(1),即要使

an(x1+pa- 1t)n+an- 1(x1+pa- 1t)n- 1+L+a1(x1+pa- 1t)+a0º 0 (mod pa) (4)

f(x1)+pa- 1tf¢(x1)º 0 (mod pa)

tf¢(x1)º-(modp)                  (5)

下面考虑两种情形。

()  f¢(x)0 (mod p),则关于t的同余方程(5)有唯一解tºt0 (modp),即t =t0+pkkÎZ),于是

xºx1+pa- 1t0 (modpa)

是同余方程(1)的解。

(f¢(x1)º 0 (modp),并且f(x1)º 0 (mod pa),则式(5)对于任意的整数t成立,即同余方程(5)p个解

tºi(mod p)0£i £p - 1

于是xºx1+pa- 1i(modpa)0£i £p - 1,都是同余方程(1)的解。证毕。

在定理中,没有对f¢(x1)º 0 (mod p)并且 f(x1)0 (mod pa)的情形进行讨论。事实上,此时,同余方程(5)无解。即,我们无法从同余方程(2)的解x1出发去求得同余方程(1)的解。

由定理,可以把解同余方程(1),转化为解同余方程

f(x)º 0 (modp)                     (6)

事实上,由方程(6)的解,利用定理,可以求出方程f(x)º 0 (modp2)的解,再利用定理,又可以求出方程f(x)º 0 (mod p3)的解,LL,直到求出方程(1)的解。

#include<stdio.h>#include<stdlib.h>#include<vector>using namespace std;typedef __int64 II;int gcd(int a,int b){    return b==0? a:gcd(b,a%b);}typedef struct {    int deg,a[15];}function;function f,diff;II op(function f, II i){    II ret=0;    for(int loop=f.deg;loop>=0;loop--){        ret=ret*i+(II)f.a[loop];    }    return ret;}II op(function f, II i, II mod){    II ret=0;    for(int loop=f.deg;loop>=0;loop--){                ret=ret*i+f.a[loop];        ret=ret%mod;    }    return ret;}II mm(II a,II b,II c){    if(b==0) return 1%c;    II tmp=mm(a,b/2,c);    return tmp*tmp%c*(b%2? a:1)%c;}II ext_gcd(II a,II &x,II b,II &y){//a*x+b*y=(x,y)=d    if(b==0){        x=1;y=0;        return a;    }    II xx,yy,d=ext_gcd(b,xx,a%b,yy);    x=yy;    y=xx-a/b*yy;    return d;}vector<II> linear(II a,II b,II m){//ax=b(mod m)    a%=m,b%=m;    vector<II> ret;    ret.clear();    II x,y,d=ext_gcd(a,x,m,y);    //if(d<0) d=-d;    if(b%d==0){        II e=(x*(b/d)%m+m)%m;//»ù´¡½â        //for(int i=0;i<(d<0? -d:d);i++) ret.push_back((e+i*(m/d))%m);        ret.push_back(e);    }    return ret;}int main(){        int T;    II pri,p2;    scanf("%d",&T);    for(int cas=1;cas<=T;cas++){        scanf("%d",&f.deg);        for(int i=f.deg;i>=0;i--) scanf("%d",&f.a[i]);        scanf("%I64d",&pri);        p2=pri*pri;        II i;        for(i=0;i<pri;i++)            if(op(f,i,pri)==0) break;        if(i>=pri) {printf("Case #%d: No solution!\n",cas);continue;}        diff.deg=f.deg-1;        for(int loop=f.deg-1;loop>=0;loop--){            diff.a[loop]=f.a[loop+1]*(loop+1);//?        }        II fx1=op(diff,i),t;        if(fx1%pri!=0){//fx1Óëpri»¥ÖÊ             II fx=op(f,i);            vector<II> fuck=linear(fx1,-fx/pri,pri);            t=fuck[0];            printf("Case #%d: %I64d\n",cas,((i+t*pri)%p2+p2)%p2);        }else{            II fx=op(f,i);            if(fx%p2==0) printf("Case #%d: %I64d\n",cas,i);            else printf("Case #%d: No solution!\n",cas);        }            }    //while(1);    return 0;   }         


 

原创粉丝点击