描述

萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1。例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7=3,3×5 mod 7=1。如果继续乘下去,就会陷入循环当中。
萌蛋还发现,这个循环的长度经常会是φ(n),即小于n且与n互质的正整数的个数。例如,φ(7)=6,而上述循环的长度也是6,因为5,4,6,2,3,1共有6个数。
再如n=6,那么5×5 mod 6=1。这个循环的长度很短,只有2,而恰好φ(6)=2。
然而,对于某些情况,虽然循环的长度可以是φ(n),但存在比φ(n)更小的长度:例如n=7,而2×2 mod 7=4,4×2 mod 7=1,循环的长度只有3。当然,6也可以是一个循环的长度。
假设已知了n,我们称数a神奇的,当且仅当关于数a的循环长度可以是φ(n),而且不存在比φ(n)更小长度的循环。例如对于n=7,5是神奇的,而2不是神奇的。
现在给出n和q次询问,每次询问给出a,问a是否是神奇的。

输入格式

第一行两个整数n q。n≤10,000,000,q≤100,000,0≤a<n。
第二行有q个整数,每个表示一个a。

输出格式

输出q个字符,1表示这个数是神奇的,0表示这个数不是神奇的。

样例输入

7 3
5 2 0

样例输出

100
首先我们用O(sqrt(n))的时间求出fai(n),然后对于每一个数a,进行一次快速幂算出afai(n)Mod n是否为1,不为1则直接输出0即可。
题目中已经告知循环的长度必定为fai(n)的因数,那么我们事先用sqrt(n)的时间求出fai(n)的所有因数,那么一个数的因数是log(n)级别的,于是对于每一个因数进行快速幂判断是否神奇,总复杂度loglogn

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <set>
11 #include <list>
12 #include <vector>
13 #include <ctime>
14 #include <iterator>
15 #include <functional>
16 #define pritnf printf
17 #define scafn scanf
18 #define For(i,j,k) for(int i=(j);i<=(k);(i)++)
19 using namespace std;
20 typedef long long LL;
21 typedef unsigned int Uint; 
22 const int INF=0x7ffffff;
23 //==============struct declaration==============
24 
25 //==============var declaration=================
26 LL bound;
27 vector <LL> fact;
28 int siz;
29 //==============function declaration============
30 int fai(LL x);
31 int gcd(LL a,LL b){return a%b==0?b:gcd(b,a%b);}
32 bool loop(LL x,LL Mod);
33 void divide(LL x);
34 LL quickpow(int x,int Exp,LL Mod);
35 //==============main code=======================
36 int main()
37 {  
38   LL Mod,q;
39   scanf("%lld%lld",&Mod,&q);
40   bound=fai(Mod);divide(bound);
41   while (q--){
42     LL query;
43     scanf("%lld",&query);
44     if (gcd(query,Mod)!=1)//可以证明如果不互质是不可能循环的
45                                      //此处用quickpow亦可,时间复杂度均为log(n)
46       putchar('0');
47     else if (loop(query,Mod))
48       putchar('1');
49     else 
50       putchar('0');
51   }
52   return 0;
53 }
54 //================fuction code====================
55 int fai(LL x)//欧拉函数
56 {
57    LL res=x;
58    LL m=sqrt(x+0.5);
59    for(LL i=2;i<=m;i++){
60      if (x%i==0){
61        res=res/i*(i-1);
62        while (x%i==0)
63          x/=i;
64      }
65    }  
66    if (x!=1)
67      res=res/x*(x-1);
68    return res;
69 }
70 bool loop(LL x,LL Mod)//判断是否神奇
71 {
72   for(int i=0;i<=siz;i++)
73     if (quickpow(x,fact[i],Mod)==1)
74       return false;
75   return true;
76 }
77 void divide(LL x)//分解因数
78 {
79   int m=sqrt(x+0.5);
80   For(i,2,m)
81     if (x%i==0){
82       fact.push_back(i);
83       fact.push_back(x/i);
84     }
85   sort(fact.begin(),fact.end());
86   siz=fact.size()-1;
87 }
88 LL quickpow(int x,int Exp,LL Mod)//快速幂
89 {
90   if (Exp==0)
91     return 1;
92   if (Exp==1)
93     return x;
94   LL t=quickpow(x,Exp/2,Mod);
95   t=(t*t)%Mod;
96   if (Exp&1)
97     t=(t*x)%Mod;
98   return t;
99 }
T1代码

相关文章:

  • 2021-07-23
  • 2021-10-24
  • 2021-09-10
  • 2021-06-01
  • 2021-11-09
  • 2021-08-29
  • 2021-09-19
  • 2021-05-27
猜你喜欢
  • 2021-07-19
  • 2022-01-07
  • 2021-05-28
  • 2022-12-23
  • 2021-07-10
  • 2022-01-17
  • 2021-06-18
相关资源
相似解决方案