• 51nod1135(求最小原根)


    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135

    题意:中文题诶~

    思路:设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)给出1个质数P,找出P最小的原根。

    我们先了解一下阶的概念:满足 a^r Ξ (1 mod m) ---1 的最小 r 即为 a%m的阶,我们可以直接从小到大枚举a, 然后将 r= φ(m) 带入进去,

    判断如果满足  1式(即 a^x%m=1当且仅当 x=r 时成立)的话即为我们所求的答案。又因为输入的 m为质数,所以 r= φ(m)=m-1. 

    判断对于当前 a,x=m-1 是否是 a^x%m=1---2 成立的唯一解我们不可能直接从正面枚举每个x,因为我们并不知道是否存在一个数 n, x>n时2式一定不成立,也就是我们不能确定枚举 x 的范围,那么枚举 x 也就无从谈起咯。不过还有有这样一个定理 对 (m-1) 只因分解成 m1, m2, m3....mk,若存在 x=(m-1)/mi 使得式2成立,那么

    当前 a 不是 a mod m 的原根。所以我们就可以从反面枚举 x 啦,若当前 a 使得 x=(m-1)/mi (1<=i<=k)对于式2都不满足, 那么当前 a 即为所求解啦~

    代码: 

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 #define MAXN 100
     4 using namespace std;
     5 
     6 ll prime[MAXN];
     7 int cnt=0;
     8 
     9 void make_prime(ll x){
    10     for(int i=2; i*i<=x; i++){
    11         if(x%i==0){
    12             prime[cnt++]=i;
    13             while(x%i==0){
    14                 x/=i;
    15             }
    16         }
    17     }
    18     if(x>1){
    19         prime[cnt++]=x;
    20     }
    21 }
    22 
    23 ll get_pow(ll x, int n, int mod){
    24     ll ans=1;
    25     while(n){
    26         if(n&1){
    27             ans=ans*x%mod;
    28         }
    29         x=x*x%mod;
    30         n>>=1;
    31     }
    32     if(ans<0){
    33         ans+=mod;
    34     }
    35     return ans;
    36 }
    37 
    38 int main(void){
    39     ll m;
    40     scanf("%lld", &m);
    41     make_prime(m-1);
    42     for(int i=2; i<m; i++){
    43         int flag=1;
    44         for(int j=0; j<cnt; j++){
    45             int x=(m-1)/prime[j];
    46             if(get_pow(i, x, m)==1){
    47                 flag=0;
    48                 break;
    49             }
    50         }
    51         if(flag){
    52             printf("%d
    ", i);
    53             return 0;
    54         }
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    pat 1034 Head of a Gang (30分)
    pta坑点
    Devc++ 编译 c++11
    Invitation Cards dijkstra法
    Cube Stacking
    畅通工程
    蚂蚁上树
    洛谷 P1439 【模板】最长公共子序列
    Recursive sequence
    A Simple Math Problem
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6219868.html
Copyright © 2020-2023  润新知