之前说道模意义下开根号

貌似就剩这一个锅了

今天就mie了她

Question:

给定方程 x ^ n ≡ a (mod p) 求x (p为质数)

Solution:

仍然考虑枚举 发现无法优化

考虑拆分 发现左边全是x没法拆...

由于我们先解决了离散对数问题 所以考虑转化

把x和a都转化成指数形式就可以解决

于是问题就变为g^(bn) ≡ g^c(mod p)

由于p是质数 所以如果欧拉定理优化就是bn≡c(mod p-1)

先不考虑g的问题 如果知道c就直接逆元就好了

然后如果知道g  c也可以由BSGS求出来

所以问题转化为 对于一个质数p 求出一个g 使得g的0~p-2次方与1~p-1一一对应

我们给这个东西起名为 原根

总体来说也是一种暴力 然后根据玄学证明(实际还是比较简单的,跟上面过程差不多) 可以得出

验证p-1所有的素因子p[i]是否都没有g ^ (p - 1 / p[i]) ≡ 1 等价于验证所有[1~p]的数是否完全剩余

Code:并没有代码

(啪!)

Code by 学姐

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <ctime>
  7 //#define ivorysi
  8 #define MAXN 100005
  9 #define eps 1e-7
 10 #define mo 974711
 11 using namespace std;
 12 typedef long long int64;
 13 typedef unsigned int u32;
 14 typedef double db;
 15 int64 A,B,C,G,eu;
 16 int64 ans[MAXN],tmp[MAXN],R,L[MAXN],cntL;
 17 int M;
 18 struct node {
 19     int next,num;
 20     int64 hsh;
 21 }E[MAXN];
 22 int head[mo + 5],sumE;
 23 int64 fpow(int64 x,int64 c,int64 MOD) {
 24     int64 res = 1,t = x;
 25     while(c) {
 26     if(c & 1) res = res * t % MOD;
 27     t = t * t % MOD;
 28     c >>= 1;
 29     }
 30     return res;
 31 }
 32 int primitive_root(int64 P,int64 eu) {
 33     static int64 factor[1005];
 34     int cnt = 0;
 35     int64 x = eu;
 36     for(int64 i = 2 ; i <= x / i ; ++i) {
 37     if(x % i == 0) {
 38         factor[++cnt] = i;
 39         while(x % i == 0) x /= i;
 40     }
 41     }
 42     if(x > 1) factor[++cnt] = x;
 43     for(int G = 2 ;  ; ++G) {
 44     for(int j = 1 ; j <= cnt ; ++j) {
 45         if(fpow(G,eu / factor[j],P) == 1) goto fail;
 46     }
 47     return G;
 48         fail:;
 49     }
 50 }
 51 int64 gcd(int64 a,int64 b) {
 52     return b == 0 ? a : gcd(b,a % b);
 53 }
 54 void ex_gcd(int64 a,int64 b,int64 &x,int64 &y) {
 55     if(b == 0) {
 56     x = 1,y = 0;
 57     }
 58     else {
 59     ex_gcd(b,a % b,y,x);
 60     y -= a / b * x;
 61     }
 62 }
 63 int64 Inv(int64 num,int64 MOD) {
 64     int64 x,y;
 65     ex_gcd(num,MOD,x,y);
 66     x %= MOD;x += MOD;
 67     return x % MOD;
 68 }
 69 void add(int u,int64 val,int num) {
 70     E[++sumE].hsh = val;
 71     E[sumE].next = head[u];
 72     E[sumE].num = num;
 73     head[u] = sumE;
 74 }
 75 void Insert(int64 val,int num) {
 76     int u = val % mo;
 77     for(int i = head[u] ; i ; i = E[i].next) {
 78     if(val == E[i].hsh) {
 79         E[i].num = num;
 80         return;
 81     }
 82     }
 83     add(u,val,num);
 84 }
 85 int Query(int64 val) {
 86     int u = val % mo;
 87     for(int i = head[u] ; i ; i = E[i].next) {
 88     if(val == E[i].hsh) {
 89         return E[i].num;
 90     }
 91     }
 92     return -1;
 93 }
 94 int BSGS(int64 A,int64 C,int64 P) {
 95     memset(head,0,sizeof(head));sumE = 0;
 96     int64 S = sqrt(P);
 97     int64 t = 1,invt = 1,invA = Inv(A,P);
 98
 99     for(int i = 0 ; i < S ; ++i) {
100     if(t == C) return i;
101     Insert(invt * C % P,i);
102     t = t * A % P;
103     invt = invt * invA % P;
104     }
105     int64 tmp = t;
106     for(int i = 1 ; i * S < P ; ++i) {
107     int x = Query(tmp);
108     if(x != -1) {
109         return i * S + x;
110     }
111     tmp = tmp * t % P;
112     }
113 }
114 bool Process(int64 A,int64 C,int64 P,int k) {
115     int64 MOD = 1,g;
116     for(int i = 1 ; i <= k ; ++i) MOD *= P;
117     cntL = 0;
118     if(C % MOD == 0) {
119     int64 T = (k - 1) / A + 1;
120     L[++cntL] = 0;
121     if(T < k) {
122         int64 num = fpow(P,T,MOD);
123         for(int i = 1 ; i * num < MOD ; ++i) L[++cntL] = i * num;
124     }
125     }
126     else if(g = gcd(C % MOD,MOD) != 1){
127     int64 x = C % MOD;
128     int c = 0;
129     while(x % P == 0) ++c,x /= P;
130     if(c % A != 0) return false;
131     G = primitive_root(MOD / (C / x),eu / (C / x));
132     eu /= C / x;
133     int e = BSGS(G,x,MOD / (C / x));
134     g = gcd(A,eu);
135     if(e % g != 0) return false;
136     e /= g;
137     int64 s = Inv(A / g,eu / g) * e % (eu / g);
138     L[++cntL] = s;
139     while(1) {
140         if((L[cntL] + eu / g) % (eu * (C / x)) == L[1]) break;
141         L[cntL + 1] = L[cntL] + eu / g;
142         ++cntL;
143     }
144     for(int i = 1 ; i <= cntL ; ++i) {
145         L[i] = fpow(G,L[i],MOD) * fpow(P,c / A,MOD) % MOD;
146     }
147     }
148     else {
149     int e = BSGS(G,C % MOD,MOD);
150     g = gcd(A,eu);
151     if(e % g != 0) return false;e /= g;
152     int s = Inv(A / g,eu / g) * e % (eu / g);
153     L[++cntL] = s;
154     while(1) {
155         if(L[cntL] + eu / g >= eu) break;
156         L[cntL + 1] = L[cntL] + eu / g;
157         ++cntL;
158     }
159     for(int i = 1 ; i <= cntL ; ++i) L[i] = fpow(G,L[i],MOD);
160     }
161     if(!cntL) return false;
162     if(!M) {
163     M = cntL;
164     for(int i = 1 ; i <= M ; ++i) ans[i] = L[i];
165     sort(ans + 1,ans + M + 1);
166     M = unique(ans + 1,ans + M + 1) - ans - 1;
167     R = MOD;
168     return true;
169     }
170     int tot = 0;
171     for(int i = 1 ; i <= M ; ++i) {
172     for(int j = 1 ; j <= cntL ; ++j) {
173         tmp[++tot] = (R * Inv(R,MOD) % (R * MOD) * (L[j] - ans[i]) + ans[i]) % (R * MOD);
174         tmp[tot] = (tmp[tot] + R * MOD) % (R * MOD);
175     }
176     }
177     R *= MOD;
178     sort(tmp + 1,tmp + tot + 1);
179     tot = unique(tmp + 1,tmp + tot + 1) - tmp - 1;
180     for(int i = 1 ; i <= tot ; ++i) ans[i] = tmp[i];
181     M = tot;
182     return true;
183 }
184 void Solve() {
185     M = 0;
186     if(B % 2 == 0) {
187     int64 Now = 2;B /= 2;
188     if(C & 1) ans[++M] = 1;
189     else ans[++M] = 0;
190
191     while(B % 2 == 0) {
192         B /= 2;
193         Now *= 2;
194         int t = 0;
195         for(int i = 1 ; i <= M ;++i) {
196         if(fpow(ans[i],A,Now) == C % Now) tmp[++t] = ans[i];
197         if(fpow(ans[i] + Now / 2,A,Now) == C % Now) tmp[++t] = ans[i] + Now / 2;
198         }
199         for(int i = 1 ; i <= t ; ++i) ans[i] = tmp[i];
200         if(!t) goto fail;
201         M = t;
202     }
203     R = Now;
204     sort(ans + 1,ans + M + 1);
205     M = unique(ans + 1,ans + M + 1) - ans - 1;
206     }
207     for(int64 i = 3 ; i <= B / i ; ++i) {
208     if(B % i == 0) {
209         eu = (i - 1);
210         B /= i;
211         int num = i,cnt = 1;
212         while(B % i == 0) {
213         B /= i;eu *= i;num *= i;++cnt;
214         }
215         G = primitive_root(num,eu);
216         if(!Process(A,C,i,cnt)) goto fail;
217     }
218     }
219     if(B > 1) {
220     eu = B - 1;
221     G = primitive_root(B,eu);
222     if(!Process(A,C,B,1)) goto fail;
223     }
224     if(M == 0) goto fail;
225     sort(ans + 1,ans + M + 1);
226     for(int i = 1 ; i <= M ; ++i) {
227     printf("%d%c",ans[i]," \n"[i == M]);
228     }
229     return;
230     fail:
231     puts("No Solution");
232 }
233 int main() {
234 #ifdef ivorysi
235     freopen("f1.in","r",stdin);
236 #endif
237     int T;
238     scanf("%d",&T);
239     while(T--) {
240     scanf("%lld%lld%lld",&A,&B,&C);
241     Solve();
242     }
243 }

View Code

转载于:https://www.cnblogs.com/yuyanjiaB/p/9803963.html

N次剩余 最基础的laji入门相关推荐

  1. 《零基础掌握 Python 入门到实战》笔记

    Python 零基础掌握 Python 入门到实战笔记 文章目录 Python 内置对象类型 基本交互语句 常用内置函数 整数与浮点数 基本数学运算 高级数学运算 字符串 序列 索引 切片 成员函数 ...

  2. 零基础Python培训入门 教你认识下这些基础内容

    Python编程语言为什么近些年这么火?从它本身的语言特性来看,Python编程简单而且直接,适合初学编程者,让初学者能够专注于编程逻辑,而不是在不流通的语法细节上感到困惑.零基础Python培训中心 ...

  3. python编程基础语法-Python编程基础语法快速入门

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  4. 零基础编程入门python视频-Python编程零基础小白快速入门完整全系列精品课

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  5. 【Python基础】快速入门Python(讲解、习题)

    0.导语 Python是一种跨平台的计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的 ...

  6. Oracle数据库基础教程:入门其实很简单

    为什么80%的码农都做不了架构师?>>>    Oracle数据库基础教程:入门其实很简单 Oracle数据库系统是目前最流行的客户/服务器数据库之一.本文集从初学者的角度出发,由浅 ...

  7. 19年8月 字母哥 第一章 spring boot 2.x基础及概念入门 这里全部看完了 热部署没出来 第二章在前面2页 用热点公司网不行

    http://springboot.zimug.com/1233100   文档 http://www.zimug.com/page/5     字母哥个人博客 11111 第一章 spring bo ...

  8. Java零基础并发编程入门

    Java零基础并发编程入门 并发编程主要包括: 线程,同步,future,锁,fork/join, volatile,信号量,cas(原子性,可见性,顺序一致性),临界性,分布式 了解基础: JMM: ...

  9. plc维修入门与故障处理实例_电气控制基础+PLC编程入门+工程应用实例

    以S7-300/400PLC为主线 电气控制基础+PLC编程入门+工程应用实例 点击图片  购买 编辑推荐1.西门子S7300/400PLC应用广.市场占有率高 2.本书通过大量的实验案例和真实的工程 ...

  10. python基础教程博客_Python基础教程_Python入门知识

    Python基础教程频道为编程初学者提供入门前的所有基础知识,必须要掌握的一些PYTHON基础语法语句,基本的数据类型. 让大家可以更快速.更容易理解的的方式掌握Python编程所需要的基础知识,灵活 ...

最新文章

  1. HikariPool 连接池问题
  2. hdu5386(暴力)
  3. OpenCASCADE:Foundation Classes数据类型
  4. react Native 环境安装配置——图解版一目了然
  5. htaccess配置文件是什么
  6. Texlive source
  7. INIT: vesion 2.88 booting
  8. UAT测试和SIT测试
  9. Other | 十招教你找到海量PPT模板
  10. 这些曾盛极一时的经典软件,现在再看,还是记忆犹新
  11. 上海师大计算机科学与技术,上海师大计算机科学与技术专业本科文凭、国家承认可查证书...
  12. SolidWorks2021导出带材质的OBJ文件
  13. linux解密shadow_Linux /etc/shadow(影子文件)内容解析(超详细)
  14. CSS之vmin和vmax
  15. hdu4565 so easy 矩阵
  16. vue打开新的标签页
  17. Linux驱动开发之常见error汇总
  18. 如何使用kodi Mac安装中文插件
  19. Python自动生成ffmpeg转码HEVC (X265,H265) 命令
  20. pl/sql模拟登录并获取Oracle ebs职责

热门文章

  1. android音乐播放器flac,无损高保真音乐播放器app
  2. Ubuntu 网易云音乐 Linux 官方版本下载安装
  3. 深入理解计算机系统03——程序的机器级表示
  4. c#加粗代码_如何使用C#加粗Excel工作表中特定行或单元格的字体?
  5. 几种微弱信号处理电路
  6. 我也撸了一个古诗词网站
  7. 【MyBatis基础】(09)- 逆向工程(代码自动生成)
  8. Oracle数据库SQL技术——习题1
  9. feifeicms 人物标签调用
  10. java doc字数_word怎么看不算标点的字数(word统计字数去掉符号)