Ural 1456. Jedi Riddle 2 整数的阶

1456. Jedi Riddle 2

Time limit: 0.25 second
Memory limit: 64 MB

Background

Everyone wants to be respected and famous. At that many of us forget that most people became respected and famous after death only. For instance, let us take system administrator Vasily "Jedi Master" Slipman. For the first time his name was mentioned in connection with the sensational case concerning password decoding. That time nearly a half of the humanity strived for getting access to an archive, which contained some information of great pith and moment (this story is fully described in the problem  "Jedi riddle").
After that case, the greatest cryptography scientists became interested in uncommon personality of Mr. Slipman and his research activities. In-depth study of Vasily's scientific heritage revealed, that during the last years of his life he was trying to understand the nature of the Force itself. Mr. Slipman tried to find the legendary Number of Force. In the volume XII of "The Book of the Light and the Darkness" an amazing experiment is described in detail:

Problem

"...And I took the Number of Light A and the Number of Darkness N. However the Darkness and the Light cannot be disjointed, so I took the One since Its essence is unknowable and sacred. And then I multiplied the One by the Number of Light, divided the result by the Number of Darkness and took the Remainder Z[1] = (1*A) modulo N. Then I multiplied the Remainder by the Number of Light, divided the result by the Number of Darkness and took the Remainder Z[2] = (Z[1]*A) modulo N once more. Being impatient, I was multiplying, dividing and taking the new Remainders Z[i] again and again... Until the day came when I understood I had been blind. The One is a key to the Force, the Alpha and the Omega, the Beginning and the Ending. I returned to my work with the eagerness I had never felt before. Because I knew - the Number of Force X will be found as soon as some Remainder Z[X] is equal to the One. And may the Force be with me..."

Input

The only line contains the integer Numbers A and N (2 ≤ A < N ≤ 10 9).

Output

You should output the minimal positive Number X, if it exists. Otherwise you should output zero.

Sample

input output
7 20
4

Hint

In the sample, the Remainders Z[1] = (1*7) modulo 20 = 7, Z[2] = (7*7) modulo 20 = 9, Z[3] = (9*7) modulo 20 = 3 and Z[4] = (3*7) modulo 20 = 1.
Problem Author: Ilya Grebnov, Dmitry Kovalioff, Nikita Rybak
Problem Source: Timus Top Coders: Second Challenge
题意:给出两个数a,m,求a对m的阶。
分析:gcd(a,m)=1时,a对m的阶才存在。
先求出phi(m),最后求出a的阶(从小到大枚举phi(m)的所有因子)。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int prime[100000];
int c2;
int pr[1000003];
void sieve()
{
    for(int i=3; i<1000003; i+=2)
        pr[i]=1;
    pr[2]=1;
    prime[c2++]=2;
    for(int i=3; i<1000003; i+=2)
    {
        if(pr[i])
        {
            prime[c2++]=i;
            for(int j=2*i; j<1000003; j+=i)
                pr[j]=0;
        }
    }
}
int phi(int n)
{
    long long ans=n;
    for(int i=0; prime[i]*prime[i]<=n&&i<c2; i++)
    {
        if(n%prime[i]==0)
        {
            ans=ans/prime[i];
            ans*=(prime[i]-1);
            while(n%prime[i]==0)
                n/=prime[i];
        }
    }
    if(n!=1)
    {
        ans/=n;
        ans*=(n-1);
    }
    return ans;
}
long long bigm(long long a,int p,int md)
{
    if(p==0)
        return 1%md;
    if(p%2==0)
    {
        long long x=bigm(a,p/2,md);
        return (x*x)%md;
    }
    else
    {
        long long x=bigm(a,p-1,md);
        return (x*a)%md;
    }
}

int main()
{
    sieve();
    int a,n;
    scanf("%d%d",&a,&n);
    int ans=0;
    for(int i=1; i*i<=phi(n); i++)
    {
        if(phi(n)%i==0)
        {
            if(bigm(a,i,n)==1)
            {
                if(ans==0) ans=i;
                else ans=min(ans,i);
            }
            if(bigm(a,phi(n)/i,n)==1)
            {
                if(ans==0) ans=phi(n)/i;
                else ans=min(ans,phi(n)/i);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值