bzoj 3031: 理科男
阿新 • • 發佈:2017-07-05
std scrip con cst 包含 測試數據 amp 分別是 col
“……就是這個問題。我覺得這個問題好糾結啊……”
Vani淡定地說完這句話。
“啊?!哈啊?!”Output
R即為求$\frac{B}{gcd(B,K^M)}$在模K意義下與K互質的數構成的乘法群中的階,答案是$\phi(K)$的約數,可以試除得到
Description
吃過草莓刨冰之後,Vani和cl有些疲倦地坐在一個長椅上。
“吶,玩得開心嗎?”Vani忽然問道。
“嗯……很,很開心的說。”
“那麽,我有一個問題想要問你呢。”
cl的臉有點紅了起來。
“嗯……好吧。問、問吧……我會告訴你的哦……”
“那好。對於一個分數A / B……”
“嗯……哎?哎?!”
“……就是這個問題。我覺得這個問題好糾結啊……”
Vani淡定地說完這句話。
“啊?!哈啊?!”
對於給定的分數 A / B,求其在 K 進制下是有限小數還是循環小數。如果是有限小數,求小數點後的位數;如果是循環小數,則求混循環部分和循環節的長度又分別是多少。
註意,循環節指的是最短循環節,且混循環部分的長度也指最短。
Input
第一行一個正整數 T,表示測試數據的數目。
每個測試數據包含三個空格分隔的整數 A, B, K。含義如題目所示。
Output
對於每個測試數據,在單獨的一行內輸出兩個空格分隔的整數 M, R。
其中 M 表示混循環部分的長度,R 表示循環節的長度。
如果 A / B 在 K 進制下是有限小數,則 R = 0,M 為小數點後面的位數;如果 A / B 在 K 進制下是純循環小數,則 M = 0。
#include<cstdio> typedef long long i64; i64 gcd(i64 a,i64 b){ for(i64 c;b;c=a,a=b,b=c%b); return a; } i64 phi(i64 x){ i64 y=x; for(int i=2;i64(i)*i<=x;++i)if(x%i==0){ y=y/i*(i-1); do x/=i;while(x%i==0); } if(x>1)y=y/x*(x-1); return y; } i64 mul(i64 a,i64 b,i64 p){ i64 c=0; for(;b;b>>=1,a=(a<<1)%p)if(b&1)c=(c+a)%p; return c; } i64 pw(i64 a,i64 n,i64 p){ i64 v=1; for(;n;n>>=1,a=mul(a,a,p))if(n&1)v=mul(v,a,p); return v; } i64 cal(i64 A,i64 B){ i64 x=phi(B),y=x; for(int i=2;i64(i)*i<=x;++i)if(x%i==0){ while(y%i==0&&pw(A,y/i,B)==1)y/=i; do x/=i;while(x%i==0); } if(x>1&&pw(A,y/x,B)==1)y/=x; return y; } int main(){ int T; for(scanf("%d",&T);T;--T){ i64 a,b,c; scanf("%lld%lld%lld",&a,&b,&c); i64 g=gcd(a,b); a/=g,b/=g; int a1=0; while(1){ i64 x=gcd(b,c); if(x==1)break; b/=x; ++a1; } printf("%d %lld\n",a1,b==1?0ll:cal(c,b)); } return 0; }
bzoj 3031: 理科男