您的位置:首页 > 其它

hdu 4320 Arcane Numbers 1

2012-07-31 21:05 267 查看


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

3
5 5
2 3
1000 2000


Sample Output

Case #1: YES
Case #2: NO
Case #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 200
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: