poj1248 (线性筛欧拉函数)(原根)

强烈鸣谢wddwjlss

题目大意:给出一个奇素数,求出他的原根的个数,多组数据。

这里先介绍一些基本性质


(a,m)=1 ( a , m ) = 1 ,满足 ar1(modm) a r ≡ 1 ( mod m ) 的最小正整数r叫做整数a模m的阶

那么给出一个定理:
(a,m)=1 ( a , m ) = 1 ,r为a摸m的阶,则对于每个正整数k, ak1(modm) a k ≡ 1 ( mod m ) 当且仅当 r|k r | k ,特别地, r|ϕm r | ϕ ( m )

阶的一些性质

(a,m)=1 ( a , m ) = 1 ,r为a摸m的阶,当且仅当二条件成立:
ar1(modm) a r ≡ 1 ( mod m )
对于 r r 的每个素因子p有ar/p1(modm)

原根

若整数a模m的阶为 ϕ(m) ϕ ( m ) ,则a是模m的原根

对于正整数m,模m具有原根当且仅当 m=2,4,pa,2pa m = 2 , 4 , p a , 2 p a 其中p是奇素数,且 a1 a ≥ 1

判断原根的方法
g是不是模m的原根:

bool check(int g,int m)
{
  for (int i=2;i*i<m;i++)
  {
    if ((m-1)%i==0 && (qsm(g,i,m)==1 || qsm(g,(m-1)/i,m)==1)) return false
  }
  return true;
}

其中 m m 为 素 数 , m1ϕ(m) m − 1 是 指 ϕ ( m )

运用的是上面的第二个推论

同时!!!!一个很重要的性质

如果 p p 有原根,则它恰有ϕ(ϕ(p))个不同的原根(无论 p p 是否为素数都适用)

那么对于上述的题目

我们要求p的原根个数,其实就是求 ϕ(p1) ϕ ( p − 1 )

直接线性筛

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>

using namespace std;

inline int read()
{
  int x=0,f=1;char ch=getchar();
  while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  return x*f;
}

const int maxn = 1e5+1e2;

int check[maxn],prime[maxn],phi[maxn];
int n,m;
int tot;

void init(int n)
{
    check[1]=1;
    phi[1]=1;
    for (int i=2;i<=n;i++)
    {
       if (!check[i])
       {
          prime[++tot]=i;
          phi[i]=i-1;
       }
       for (int j=1;j<=tot;j++)
       {
        if (i*prime[j]>n) break;
        check[i*prime[j]]=1;
        if (i%prime[j]==0)
        {
            phi[i*prime[j]]=phi[i]*prime[j];
            break;
        }
        else
        {
            phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
       }
    }
}

int main()
{
  init(100000);
  while (scanf("%d",&n)!=EOF)
  {
    printf("%d\n",phi[n-1]);
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值