• 51Nod1037 最长的循环节 V2



    题目看这里
    小学奥数题目23333
    首先我们知道,0.0˙0...001˙=1/99..9
    那么任意一个循环小数都可以写成以10k1为分母的分数
    让后稍加分析就知道,满足条件的最小的k就是循环节的长度
    那么题目就变成了求一个数s,使得满足10k=1 ( mod s )这样的k最大
    我们将k记为f(s)
    首先由欧拉定理得10ϕ(s)=1(mod s)所以f(s)|ϕ(s)
    让后再根据打表的规律,我们发现满足条件的数其实非常多(密度>0.5)
    所以我们可以猜测,只有当f(s)=ϕ(s)时才能取到最多(否则2f(s)<=ϕ(s)
    于是我们采用Miller Rabin+Pollard Rho来分解质因数求ϕ,从n开始向 下枚举即可,由于密度很高,所以很快就可以得到答案

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<time.h>
    #include<vector>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define LL long long
    using namespace std;
    vector<LL> s,t,w;
    inline LL mul(LL x,LL k,LL M,LL s=0){
    for(;k;x=(x+x)%M,k>>=1) k&1?s=(s+x)%M:0;
    return s;
    }
    inline LL pow(LL x,LL k,LL M,LL s=1){
    for(;k;x=mul(x,x,M),k>>=1) k&1?s=mul(s,x,M):0;
    return s;
    }
    inline bool test(LL n,LL a,LL d){
    if(n==2 || n==a) return 1;
    if( n&1) return 0;
    while( d&1) d>>=1;
    LL t=pow(a,d,n);
    while((d!=n1)&&(t!=1)&&(t!=n1)){
    t=mul(t,t,n);
    d<<=1;
    }
    return (t==n1 || d&1);
    }
    inline bool prime(LL n){
    if(n<2) return 0;
    int a[6]={2,61,3,40357,49919,19260817};
    for(int i=0;i<5;++i)
    if(!test(n,a[i],n1)) return 0;
    return 1;
    }
    inline LL gcd(LL a,LL b){
    for(LL c;b;a=b,b=c) c=a%b;
    return a;
    }
    inline LL rho(LL n){
    begin:
    LL c=rand()%n; int i=1,k=2;
    LL x=rand()%n+1,y=x,d;
    for(;;){
    i++;
    x=(mul(x,x,n)+c)%n;
    d=gcd(xy,n);
    if(1<d && d<n) return d;
    if(y==x) goto begin;
    if(i==k){ y=x; k<<=1; }
    }
    }
    inline LL read(){
    LL x=0; char c=getchar();
    while(c>9 || c<0) c=getchar();
    while(c>=0&&c<=9){ x=(x<<3)+(x<<1)+(c48);c=getchar(); }
    return x;
    }
    LL n;
    inline void dfs(LL x){
    if(prime(x)){ s.push_back(x); return; } 
    LL y=rho(x); while(x%y==0) x/=y;
    if(x>1) dfs(x); dfs(y);
    }
    inline void dt(LL x,int i){
    if(i==s.size()){ w.push_back(x); return; }
    for(int j=0;j<=t[i];++j) dt(x,i+1),x=s[i];
    }
    int d(LL n){
    if(!prime(n)) return 0; LL m=n1;
    s.clear(); t.clear(); w.clear(); dfs(n1); 
    for(int i=0;i<s.size();++i) 
    for(t.push_back(0);m%s[i]==0;m/=s[i]) ++t[i];
    dt(1,0);
    sort(w.begin(),w.end());
    for(int i=0;i<w.size();++i) 
    if(pow(10,w[i],n)==1){
    if(w[i]==n1){ printf("%lld ",n); exit( 0 ); }
    else return 0;
    }
    }
    int main(){
    n=read();
    while(!d(n)) n;
    }

  • 相关阅读:
    fluentValidation集成到autofac
    javascript中的this
    Android环境配置Sencha Touch
    PHP上传图片如何防止图片木马?
    mysql 修改字段长度
    mysql 截取字符
    php 获取文件后缀名
    mysql 导入导出数据库、数据表
    Nginx下修改php.ini后重新加载配置文件命令
    ubuntu 12.04 LTS(64位)安装apache2
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477077.html
Copyright © 2020-2023  润新知