题意

给定一个进制分数 求是否是循环小数,且求出循环节长度

题解

暴力

il int find(int p){
int head=last[p%mod];
while(head&&pr[head].p!=p)head=pr[head].next;
if(!head)head=++siz;
return head;
} int main(){
T=gi;
while(T--){siz=0;memset(last,0,sizeof(last));
ll p,q,k;
p=gi;q=gi;k=gi;
ll d=gcd(p,q);
p/=d;q/=d;
p%=q;
for(int i=1;;i++){
p*=k;
if(!(p%q)){
printf("%d 0\n",i);
break;
}
int t=find(p);
if(!pr[t].id)pr[t]=(data){i,p};
else{
printf("%d %d\n",pr[t].id-1,i-pr[t].id);
break;
}
p%=q;
}
}
return 0;
}

正解:

首先设一个序列,表示原数小数点后i位,那么

然后余数

上面暴力是计算到这样一对的时候停止

 

那么考虑a的性质 如果 ,那么

如果 那么

就是出现了更早的重复,所以最早的重复肯定是在p=1,说明这样形式的只有纯循环小数

如果满足

于是

然后就是求一个K模B的阶的问题。

阶很好求。。

如果

那么设

重复这个过程,然后直到时,做了多少次,前面非循环部分长度就是t,求一遍阶就可以了

#include<queue>
#include<map>
#include<cstdio>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int>Pii;
const int inf=0x7fffffff;
const ll infll=(1ll<<60);
#define dbg(n) cerr<<#n"="<<n<<endl;
#define Ri register int
#define gc getchar()
#define il inline
il ll read(){
bool f=true;
register ll x=0;char ch;
while(!isdigit(ch=gc))
if(ch=='-')f=false;
while(isdigit(ch)){
x=(x<<1)+(x<<3)+ch-'0';
ch=gc;
}
return f?x:-x;
}
#define X first
#define Y second
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
inline ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
map<ll,int> Calc(ll x){
map<ll,int> prime;
for(int i=2;(ll)i*i<=x;i++)
if(x%i==0){
int sum=0;
while(x%i==0)x/=i,sum++;
prime[i]=sum;
}
if(x>1)prime[x]=1;
return prime;
}
il ll Euler_phi(ll x,const map<ll,int>& prime){
ll ans=x;
for(map<ll,int>::const_iterator i=prime.begin();i!=prime.end();i++)
if(i->Y)ans=ans/i->X*(i->X-1);
return ans;
}
il ll Mul(ll a,ll b,ll mod){
ll ans=0,p=a%mod;
while(b){
if(b&1)ans=(ans+p)%mod;
p=(p+p)%mod;
b>>=1;
}
return ans;
}
il ll Mod(ll a,ll b,ll mod){
ll ans=1,p=a%mod;
while(b){
if(b&1)ans=Mul(ans,p,mod);
p=Mul(p,p,mod);
b>>=1;
}
return ans;
}
ll A,B,K;
int main(){
int T;
cin>>T;
while(T--){
A=gi;B=gi;K=gi;
ll d=gcd(A,B);
A/=d;B/=d;
map<ll,int> prime_B=Calc(B),prime_K=Calc(K);
int M=0;ll tmpB=B;
for(map<ll,int>::const_iterator i=prime_K.begin();i!=prime_K.end();i++){
int p=prime_B[i->X];prime_B[i->X]=0;
M=max(M,(p+i->Y-1)/i->Y);
while(p)
tmpB/=i->X,p--;
}
ll R=0;
if(tmpB!=1){
ll phi_B=Euler_phi(tmpB,prime_B);
R=phi_B;
prime_B=Calc(R);
for(map<ll,int>::const_iterator i=prime_B.begin();i!=prime_B.end();i++){
int p=i->Y;
while(p){
if(Mod(K,R/i->X,tmpB)==1)
p--,R/=i->X;
else break;
}
}
}
cout<<M<<" "<<R<<endl;
}
return 0;
}

最新文章

  1. JS截字符串处理数字,汉字,英文问题
  2. JNI在C 和 C++ 函数实现的不同
  3. Java网络连接之HttpURLConnection 与 HttpClient
  4. RDS MySQL 全文检索相关问题的处理
  5. Oracle数据库入门——初级系列教程
  6. php 数组二分法查找函数
  7. 双日历插件--jq datepicker时间范围选择
  8. 2.3搭建Android应用程序开发环境
  9. c中计时的几种方法
  10. 解决读写properties属性文件
  11. spring 加载配置文件的相关配置总结
  12. 减小Cookie体积
  13. boost.asio源码阅读(1) - 从chat_server开始
  14. 【stm32】时钟树解析
  15. 近期热门微信小程序demo源码下载汇总
  16. java游戏开发杂谈 - 创建一个窗体
  17. 【转】没那么难,谈CSS的设计模式
  18. MyBatis-进阶1
  19. BZOJ3626 LNOI2014LCA(树链剖分+主席树)
  20. Socket传输简单的信息以及粘包问题的解决

热门文章

  1. Cocos2d-JS坐标系
  2. C语言知识总结(2)
  3. oracle 数据库导入导出
  4. [Guava源码分析] Preconditions 前置条件
  5. iOS获取汉字的拼音
  6. linux od命令: 按不同进制显示文件
  7. HTML5-WebWorker
  8. 使用公司自己的maven服务器时,本地 maven 的配置方法
  9. linux服务器报No space left on device错误的解决过程记录
  10. php微信开发(1):缓存access_token的方法