zoukankan      html  css  js  c++  java
  • poj 3358

      1 /**
      2      大意: 给定小数(p/q),求其循环节的大小和循环节开始的位置
      3      解法: 若出现循环 ai*2^m=  aj%p;
      4                即 2^m %p =1
      5                若2与p 互素,则可由欧拉函数的,
      6                不互素,需将其转化为互素的情况,,也就出现了循环节开始位置的差异;
      7 
      8 值得学习的地方:
      9 1、
     10 首先,先对该分数 n/m 化简。
     11              temp = gcd(n,m);
     12 //           n = n / temp
     13 //           m = m / temp
     14 //           n = n mod m
     15 //           接下来就是需要知道一个分数化成k进制小数的方法:
     16 //           for i = 0 to 需要的位数
     17 //                   n = n * k;
     18 //                   bit[i] = n / m;
     19 //       
     20 
     21 2、
     22 a ^ x % q = 1,对于其任意一个解x ,它的最小解x0 | x 。
     23 在a 与 q 互质的条件下,ψ(q) 是它的一个解。
     24 所以有x0 | ψ(q)这样一个条件,可以先求出q的欧拉函数值ψ(q),再在它的因子中找最小解。
     25 注意中间过程int可能溢出。
     26 
     27 **/
     28 
     29 #include <iostream>
     30 #include <algorithm>
     31 #include <math.h>
     32 using namespace std;
     33 long long fn[1000000];
     34 long long  gcd(long long  a,long long  b){
     35     if(b==0)
     36         return a;
     37     return gcd(b,a%b);
     38 }
     39 
     40 long long  pow(long long a,long long b,long long m){
     41     if(b==0)
     42         return 1;
     43     long long c =1;
     44     a =a%m;
     45     while(b){
     46         if(b&1)
     47             c = (long long )c*a%m;
     48         a =(long long )a*a%m;
     49         b>>=1;
     50     }
     51     return c;
     52 }
     53 
     54 long long eular(long long n){
     55     long long m = (long long  )sqrt(n+0.5);
     56     long long ans = n;
     57     for(long long i=2;i<=m;i++) if(n%i==0){
     58         ans = ans/i*(i-1);
     59         while(n%i==0)
     60             n/=i;
     61     }
     62     if(n>1)
     63         ans = ans/n*(n-1);
     64     return ans;
     65 }
     66 
     67 int main()
     68 {
     69     long long n,m;
     70     char c;
     71 
     72     long long cur =1;
     73     while(cin>>n>>c>>m){
     74         int temp = gcd(n,m);   // 注意:一上午自己就是因为这个图省劲没有先将gcd(n,m)存起来,,导致后边的m/gcd(n,m) 一直是n与m的最大公约数是1的情况,即m没有得化简。。。
     75         n = n/temp;
     76         m = m/temp;
     77         n = n%m;
     78         long long  ans1,ans2;
     79         long long t=0;
     80         while(m%2==0){
     81             m = m/2;
     82             t++;
     83         }
     84         ans1 = t+1;
     85 
     86         long long res = eular(m);
     87         if(res==1){
     88             ans2 = 1;
     89         }else{
     90             long long cnt =0;
     91            // cout<<res<<endl;
     92             for(long long i=1;i*i<=res;i++)if(res%i==0){
     93                 fn[cnt++] = i;
     94                 fn[cnt++] = res/i;
     95             }
     96             sort(fn,fn+cnt);
     97             for(long long i=0;i<cnt;i++){
     98                 if(pow(2,fn[i],m)==1){
     99                     ans2 = fn[i];
    100                     break;
    101                 }
    102             }
    103         }
    104         cout<<"Case #"<<cur++<<": "<<ans1<<","<<ans2<<endl;
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    jar-下载站点
    java-原生爬虫机制源码
    eclipse-插件安装的三种方式
    ivy,ivyde插件-eclipse
    cygwin-介绍-安装
    cygwin-使用介绍
    linux-命令全集
    jquery-遍历each
    SSD固态硬盘的闪存芯片颗粒介绍
    java-测试synchronized使用xxx.class和this使用的区别
  • 原文地址:https://www.cnblogs.com/Bang-cansee/p/3724269.html
Copyright © 2011-2022 走看看