zoukankan      html  css  js  c++  java
  • 51nod 1135 原根

    题目链接:51nod 1135 原根

    设 m 是正整数,a是整数,若a模m的阶等于φ(m),则称 a 为 模m的一个原根。(其中φ(m)表示m的欧拉函数)

    阶:gcd(a,m)=1,使得这里写图片描述成立的最小的 r,称为 a 对 模m 的 阶

    φ(m):在[1,m)的区间内与m互质的数的个数。

    求模素数p的原根a的方法:

    因为p为素数,所以φ(p)=p-1, 这题就是要找最小的a使得 a^(p-1)%p = 1 成立(根据费马小定理,该式一定成立),

    先求p-1所有不同的 质因子 p1,p2…pm,

    对任何整数 a ∈[1,p-1], 检验 a 是否为 p 的原根,

    检验方法:a^((p-1)/p1),a^((p-1)/p2),...a^((p-1)/pm) 中是否存在一个 模p 等于 1 ,

    存在的话 a 就不是 模p 的一个原根(即p-1就不是a对模p的阶),否则a就为原根。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<queue>
     6 #define CLR(a,b) memset((a),(b),sizeof((a)))
     7 using namespace std;
     8 typedef long long ll;
     9 const int N = 50000;
    10 int prime[N];//prime[0] 存的是素数的个数
    11 int ppri[N];//p-1的质因子
    12 void getPrime(){
    13     CLR(prime , 0);
    14     for(int i = 2;i < N; i++){
    15         if(!prime[i])
    16             prime[ ++prime[0] ] = i;
    17         for(int j = 1; j <= prime[0] && prime[j] <= N / i; j++){
    18             prime[ prime[j] * i ] = 1;
    19             if(i % prime[j] == 0) break;
    20         }
    21     }
    22 }
    23 ll pow_m(ll a, ll n, ll m){
    24     ll t = a % m;
    25     ll r = 1;
    26     while(n > 0){
    27         if(n & 1)
    28             r = r * t % m;
    29         t = t * t % m;
    30         n >>= 1;
    31     }
    32     return r;
    33 }
    34 int divide(int n){//分解合数n的质因子
    35     int cnt = 0;
    36     for(int i = 1; prime[i] * prime[i] <= n; ++i){
    37         if(n % prime[i] == 0){
    38             ppri[++cnt] = prime[i];
    39             while(n % prime[i] == 0){
    40                 n /= prime[i];
    41             }
    42         }
    43     }
    44     if(n > 1) ppri[++cnt] = n;
    45     return cnt;
    46 }
    47 int main(){
    48     int p, i, a, t, f;
    49     getPrime();
    50     scanf("%d", &p);
    51     int cnt = divide(p - 1);//p-1 的 质因子个数
    52     for(a = 2; a <= p - 1; ++a){//原根从 2 到 p-1 枚举
    53         f = 1;
    54         for(i = 1; i <= cnt; ++i){
    55             t = (p - 1) / ppri[i];
    56             if( pow_m(a, t, p) == 1){
    57             //存在a^((p-1)/ppr[i]) mod p = 1, 则 a 不是质数p的原根
    58                 f = 0; break;
    59             }
    60         }
    61         if(f){
    62             printf("%d
    ",a);
    63             break;
    64         }
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    You can’t access this shared folder because your organization’s security policies block unauthenticated guest access
    iOS 程序退出之后
    给网站得标签头加上小图标
    ios外界蓝牙适配
    JavaScript&jquery判断下载地址是否可用,同时判断浏览器是否禁用弹窗
    GCD初级使用
    find与xargs
    sed命令详解
    shell变量详解
    date命令详解
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/5990485.html
Copyright © 2011-2022 走看看