您的位置:首页 > 其它

Period of an Infinite Binary Expansion-----欧拉函数,欧拉定理

2012-07-11 18:52 405 查看
题目:http://poj.org/problem?id=3358
这一题很经典。

题解:源于http://www.cnblogs.com/ACKOKO/articles/2119216.html

这里讲一下2^i*(2^(j-i)-1)%q==0,为什么将q中的2的个数是i,因为2^i中的i要尽量小(i是循环的前一位,题目要求i要小),并且要满足去除q中所有的2,所以i要等于q中的2的个数。

源代码:

#include <stdio.h>
#include <algorithm>

using namespace std;

typedef long long ll;

int cnt;
int m,n,d;
int factor[1000000];

int  gcd(int a,int b)
{
    if(b==0)  return a;
    return gcd(b,a%b);
}
int euler(int m)
{
    int s=m;
    for(int i=2;i*i<=m;i++)
     {
         if(m%i==0)
         {
             while(m%i==0) {m=m/i;}
             s=s/i*(i-1);
         }
     }
     if(m>1)
     s=s/m*(m-1);
     return s;
}

ll quickPow(int b,int m)
{
   ll  s=1,a=2;
   while(b>0)
   {
     if(b%2==1) s=s*a%m;
     a=a*a%m;
     b=b/2;
   }
   return s;
}

int solve(int  m)
{
    int flag=0,y,k=0;
    int sum,x=euler(m);
     if(x==1)  return 1;
     for(int i=2;i*i<=x;i++)
      if(x%i==0)
      {
          factor[k++]=i;
          factor[k++]=x/i;
      }
      sort(factor,factor+k);
      for(int i=0;i<k;i++)
          {
              sum=quickPow(factor[i],m);
              if(sum==1)
              {
                  y=factor[i];
                 flag=1;
                break;
              }
           }
       if(!flag) y=x;
      return y;
 }
int   main(){
   int  cas=1;
   while(scanf("%d/%d",&n,&m)!=EOF)
  {
      cnt=1;
      d=gcd(n,m);
      n=n/d;  m=m/d;
      while(m%2==0)
      {
          m=m/2;
          cnt++;
      }
      printf("Case #%d: %d,%d\n",cas++,cnt,solve(m));
  }
   return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: