hdu 4320 Arcane Numbers 1

来源:互联网 发布:网络信用查询 编辑:程序博客网 时间:2024/06/05 01:17

Problem Description
Vance and Shackler like playing games. One day, they are playing a game called "arcane numbers". The game is pretty simple, Vance writes down a finite decimal under base A, and then Shackler translates it under base B. If Shackler can translate it into a finite decimal, he wins, else it will be Vance’s win. Now given A and B, please help Vance to determine whether he will win or not. Note that they are playing this game using a mystery language so that A and B may be up to 10^12.
 

Input
The first line contains a single integer T, the number of test cases.
For each case, there’s a single line contains A and B.
 

Output
For each case, output “NO” if Vance will win the game. Otherwise, print “YES”. See Sample Output for more details.
 

Sample Input
35 52 31000 2000
 

Sample Output
Case #1: YESCase #2: NOCase #3: YES


代码每次都是差一点点。。。不过在YY情况下,正确的可能确实是很小。

证明如下:A到B的转换即为:1/A=x/B+y/B的平方+z/B的立方...(x,y,z为任意)

那么,A中的质因子必须全包含在B中,因为B中的质因子可以减少,却不能无故的增加。(比赛的时候写成了A中的质因子必须跟B中的相等)

代码判质因子部分用的的素数测试的模板,因为只有10的12次方,所以不用素数测试的也可以的。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<vector>#include<queue>#define time 8#define call 200using namespace std;__int64 x[10000];__int64 y[10000];__int64 sum1[10000];__int64 sum2[10000];__int64 t,tt;//============================素数判断====================================//__int64 mod_mult(__int64 a,__int64 b,__int64 n)//返回 (a*b)%n{    a=a%n;    __int64 res=0;    while(b)    {        if(b&1)        {            res+=a;            if(res>=n) res-=n;        }        a=a<<1;        if(a>=n) a-=n;        b=b>>1;    }    return res;}__int64 mod_exp(__int64 a,__int64 b,__int64 n)//返回(a^b)mod n{    a=a%n;    __int64 res=1;    while(b>=1)    {        if(b&1)            res=mod_mult(res,a,n);        a=mod_mult(a,a,n);        b=b>>1;    }    return res;}bool witness(__int64 a,__int64 n){    __int64 m,x,y;    int i,j=0;    m=n-1;    while(m%2==0)    {        m=m>>1;        j++;    }    x=mod_exp(a,m,n);    for(i=1;i<=j;i++)    {        y=mod_exp(x,2,n);        if(y==1&&x!=1 &&x!=n-1) return true;//二次探测        x=y;    }    if(y!=1)        return true;    return false;}bool miller_rabin(__int64 n,int s){    if(n==1) return true;    if(n==2) return false;    if(n%2==0) return true;    for(int i=1;i<=s;i++)//s次试探    {        __int64 a=rand()%(n-1)+1;        if(witness(a,n))            return true;    }    return false;//为素数}//=======================分解整数因子============================================//__int64 gcd(__int64 a,__int64 b){    if(b==0) return a;    return gcd(b,a%b);}__int64 pollardRho(__int64  n,int c){    int i=1;    __int64 x=rand()%n;    __int64 y=x;    int k=2;    while(1)    {        i=i+1;        x=(mod_exp(x,2,n)+c)%n;        __int64 d=gcd(y-x,n);        if(1<d&&d<n) return d;        if(y==x) return n;        if(i==k)        {            y=x;            k=k*2;        }    }}void getsmallest1(__int64 n,int c){    if(n==1) return ;    if(miller_rabin(n,time)==false)//如果为素数    {        x[t++]=n;        return ;    }    __int64 val=n;    while(val==n)        val=pollardRho(n,c--);    getsmallest1(val,c);//二分    getsmallest1(n/val,c);}void getsmallest2(__int64 n,int c){    if(n==1) return ;    if(miller_rabin(n,time)==false)//如果为素数    {        y[tt++]=n;        return ;    }    __int64 val=n;    while(val==n)        val=pollardRho(n,c--);    getsmallest2(val,c);//二分    getsmallest2(n/val,c);}int main(){    int T;    long long a,b;    while(scanf("%d",&T)!=EOF)    {        int r=1;        while(T--)        {            memset(sum1,0,sizeof(sum1));            memset(sum2,0,sizeof(sum2));            memset(x,0,sizeof(x));            memset(y,0,sizeof(y));            cin>>a>>b;                    t=0;                    getsmallest1(a,call);                    tt=0;                    getsmallest2(b,call);                    sort(x,x+t);                    sort(y,y+tt);                    int g1=0,g2=0;                    sum1[g1++]=x[0],sum2[g2++]=y[0];                    for(int i=1;i<t;i++)                    {                        if(x[i]!=x[i-1])                        {                            sum1[g1++]=x[i];                        }                    }                    for(int i=1;i<tt;i++)                    {                        if(y[i]!=y[i-1])                        {                            sum2[g2++]=y[i];                        }                    }                    int p1,q1=1;                    for(int i=0;i<g1;i++)                    {                        p1=1;                        for(int j=0;j<g2;j++)                        {                            if(sum1[i]==sum2[j])                            {                                p1=0;                                break;                            }                        }                        if(p1==1)                        {                            q1=0;                            printf("Case #%d: NO\n",r);                            break;                        }                    }                    if(q1==1)                     printf("Case #%d: YES\n",r);            r++;        }    }    return 0;}