原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1123.html

题目传送门 - 51Nod1123

题意

  $T$ 组数据。

  给定 $A,B,C$,求出使得 $x^A \equiv C \pmod B$ 的所有 $x$,保证解的个数不超过 $\sqrt B$ 。

  $T\leq 100,1\leq A,B,C \leq 10^9$

题解

  先记一下写这一题的感受:

    1. 写的过程中代码长度峰值达到过 300 行,好久没写码农题了,感到自己码力大减。

    2. 我貌似只会推 exCRT 了,互质的 CRT 我居然都记错了,而且还推错了,浪费了好多时间。

    3. BZOJ2219 的数据太水,我在做这题的时候找到了 hack 我那一题的数据……

    4. 数论真有(du)趣(liu)。

UPD(2018-09-10):

  详见数论总结。

  传送门 - https://www.cnblogs.com/zhouzhendong/p/Number-theory-Residue-System.html

代码

#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int read(){int x=0;char ch=getchar();while (!isdigit(ch))ch=getchar();while (isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();return x;
}
int pcnt,f[N],Prime[N];
void Get_Prime(int n){memset(f,0,sizeof f);pcnt=0;for (int i=2;i<=n;i++){if (f[i])continue;Prime[++pcnt]=i;for (int j=i+i;j<=n;j+=i)f[j]=1;}
}
void Divide(int x,int *p,int *q,int &cnt){cnt=0;for (int i=1;i<=pcnt&&Prime[i]*Prime[i]<=x;i++){if (x%Prime[i])continue;p[++cnt]=Prime[i],q[cnt]=0;while (x%p[cnt]==0)x/=p[cnt],q[cnt]++;}if (x>1)p[++cnt]=x,q[cnt]=1;
}
int Pow(int x,int y,int mod){int ans=1;for (;y;y>>=1,x=1LL*x*x%mod)if (y&1)ans=1LL*ans*x%mod;return ans;
}
int Pow(int x,int y){return Pow(x,y,2e9);
}
int gcd(int a,int b){return b?gcd(b,a%b):a;
}
int Fac[50],Fac_cnt=0;
bool Get_g_Check(int P,int C,int x){int phi=Pow(P,C-1)*(P-1),pw=Pow(P,C);if (C>1&&Pow(x,phi/P,pw)==1)return 0;for (int i=1;i<=Fac_cnt;i++)if (Pow(x,phi/Fac[i],pw)==1)return 0;return 1;
}
int Get_g(int P,int C){int v=P-1;Fac_cnt=0;for (int i=1;i<=pcnt&&Prime[i]*Prime[i]<=v;i++)if (v%Prime[i]==0){Fac[++Fac_cnt]=Prime[i];while (v%Prime[i]==0)v/=Prime[i];}if (v>1)Fac[++Fac_cnt]=v;for (int i=2;;i++)if (Get_g_Check(P,C,i))return i;return -1;
}
struct hash_map{static const int Ti=233,mod=1<<16;int cnt,k[mod+1],v[mod+1],nxt[mod+1],fst[mod+1];int Hash(int x){int v=x&(mod-1);return v==0?mod:v; }void clear(){cnt=0;memset(fst,0,sizeof fst);}void update(int x,int a){int y=Hash(x);for (int p=fst[y];p;p=nxt[p])if (k[p]==x){v[p]=a;return;}k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt,v[cnt]=a;return;}int find(int x){int y=Hash(x);for (int p=fst[y];p;p=nxt[p])if (k[p]==x)return v[p];return 0;}int &operator [] (int x){int y=Hash(x);for (int p=fst[y];p;p=nxt[p])if (k[p]==x)return v[p];k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt;return v[cnt]=0;}
}Map;
int BSGS(int A,int B,int P){int M=max((int)(0.8*sqrt(1.0*P)),1),AM=Pow(A,M,P);Map.clear();for (int b=0,pw=B;b<M;b++,pw=1LL*pw*A%P)Map.update(pw,b+1);for (int a=M,pw=AM;a-M<P;a+=M,pw=1LL*pw*AM%P){int v=Map.find(pw);if (v)return a-(v-1);}return -1;
}
int exgcd(int a,int b,int &x,int &y){if (!b){x=1,y=0;return a;}int res=exgcd(b,a%b,y,x);y-=(a/b)*x;return res;
}
int RHD(vector <int> &v,int A,int B,int P,int C,int flag){
//  printf("RHD :: %d %d %d %d\n",A,B,P,C);int g=Get_g(P,C);int t=BSGS(g,B,Pow(P,C));int mod=(P-1)*Pow(P,C-1),pw=mod/(P-1)*P;int GCD=gcd(mod,gcd(A,t));if (!flag)return gcd(A,mod)>GCD?0:GCD;v.clear();if (gcd(A,mod)>GCD)return 0;int _A=A/GCD,_t=t/GCD,_mod=mod/GCD;int x,y;exgcd(_A,_mod,y,x);y=(y%_mod+_mod)%_mod;y=1LL*y*_t%_mod;for (int i=y;i<mod;i+=_mod)v.push_back(Pow(g,i,pw));return GCD;
}
vector <int> tmp;
void dfs(vector <int> &v,int A,int B,int C,int t,int d){if (Pow(t,A,1<<d)!=B%(1<<d))return;if (C==d)return v.push_back(t);dfs(v,A,B,C,t,d+1);dfs(v,A,B,C,t|(1<<d),d+1);
}
int solve2(vector <int> &v,int A,int B,int C){v.clear();B%=1<<C;dfs(v,A,B,C,0,0);return (int)v.size();
}
int solve(vector <int> &v,int A,int B,int P,int C,int flag){if (P==2)return solve2(v,A,B,C);if (flag)v.clear();int pw=Pow(P,C),Phi=(P-1)*Pow(P,C-1);B%=pw;if (B==0){if (!flag)return Pow(P,C-((C+A-1)/A));int base=Pow(P,((C+A-1)/A));for (int i=0;i<pw;i+=base)v.push_back(i);return (int)v.size();}int g=gcd(B,pw),Q=0;B/=g;while (g>1)g/=P,Q++;if (!flag)return Pow(P,Q-Q/A)*((Q%A)?0:RHD(v,A,B,P,C-Q,0));if (Q%A)return 0;RHD(tmp,A,B,P,C-Q,1);int base=Pow(P,C-Q+Q/A),tg=Pow(P,Q/A);for (vector <int> :: iterator i=tmp.begin();i!=tmp.end();i++)for (int j=*i=1LL*(*i)*tg%base;j<pw;j+=base)v.push_back(j);return (int)v.size();
}
vector <int> res[50];
set <int> Ans;
int crtk[50];
void dfsCRT(int x,int d,int dcnt,int *p,int *q,int Fac){if (d>dcnt){Ans.insert(x);return;}for (int j=0;j<res[d].size();j++)dfsCRT((1LL*res[d][j]*crtk[d]+x)%Fac,d+1,dcnt,p,q,Fac);
}
int main(){Get_Prime(1e5);int T=read();while (T--){int A=read(),P=read(),B=read();int cnt,p[50],q[50];Divide(P,p,q,cnt);swap(p[1],p[cnt]);swap(q[1],q[cnt]);int ans=1;for (int i=1;i<=cnt&&ans>0;i++)ans*=solve(res[i],A,B,p[i],q[i],0);if (!ans){puts("No Solution");continue;}for (int i=1;i<=cnt;i++)solve(res[i],A,B,p[i],q[i],1);for (int i=1;i<=cnt;i++){int v1=Pow(p[i],q[i]),v2=P/Pow(p[i],q[i]),x,y;exgcd(v2,v1,x,y);x=(x%v1+v1)%v1;crtk[i]=1LL*v2*x%P;}Ans.clear();dfsCRT(0,1,cnt,p,q,P);for (set <int> :: iterator i=Ans.begin();i!=Ans.end();i++)printf("%d ",*i);puts("");}return 0;
}

  

  

转载于:https://www.cnblogs.com/zhouzhendong/p/51Nod1123.html

51Nod1123 X^A Mod B 数论 中国剩余定理 原根 BSGS相关推荐

  1. 第二十九章 数论——中国剩余定理与线性同余方程组

    第二十九章 数论--中国剩余定理与线性同余方程组 一.中国剩余定理 1.作用: 2.内容: 3.证明: (1)逆元的存在性 (2)验证定理的正确性 4.代码实现: (1)步骤: (2)问题: (3)代 ...

  2. 数论——中国剩余定理及其扩展详解

    文章目录 概述 中国剩余定理扩展 例题 总结 概述 引入: 一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作<孙子算经>卷下第二十六题,叫做"物不知数&qu ...

  3. 数学--数论--中国剩余定理 拓展 HDU 1788

    再次进行中国余数定理 问题描述 我知道部分同学最近在看中国剩余定理,就这个定理本身,还是比较简单的: 假设m1,m2,-,mk两两互素,则下面同余方程组: x≡a1(mod m1) x≡ a2(mod ...

  4. 数学--数论--中国剩余定理+扩展中国剩余定理(孙子定理)

    中国剩余定理 问题 求解同余方程组 其中m1,m2,m3...mkm_1,m_2,m_3...m_km1​,m2​,m3​...mk​为两两互质的整数 求x的最小非负整数解 定理 令M=∏i=1kmi ...

  5. ACM数论----中国剩余定理与拓展中国剩余定理

    一.问题引入: 在<孙子算经>中有这样一个问题:"今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?"这个问 ...

  6. [数论]-----中国剩余定理(扩展中国剩余定理)

    中国剩余定理 中国剩余定理(CRT)用于求形如: { x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) ⋯ ⋯ x ≡ a k ( m o d m k ) \be ...

  7. 数论 · 中国剩余定理(CRT)

    UPDATE 2021 - 12 - 10:补充扩展中国剩余定理 EXCRT,额外开了一篇博客写. 2021 - 12 - 21:修改了一两句话,更严谨一些. 问题概述 小奥里的韩信点兵问题: { x ...

  8. 数论-中国剩余定理(crt) 与拓展中国剩余定理(excrt)

    中国剩余定理(crt) [用途] 求方程组中最小的非负整数解X X ≡ { a 1 ( m o d m 1 ) a 2 ( m o d m 2 ) . . . a n ( m o d m n ) X\ ...

  9. 数论--中国剩余定理模板

    ACM常用模板合集 void exgcd(int a,int b,int &x,int &y) {if(b==0){ x=1; y=0; return;}exgcd(b,a%b,x,y ...

最新文章

  1. linux中搭建vue-cli
  2. Interview:算法岗位面试—10.23下午—上海某科技公司算法岗位(偏机器学习算法,上市)技术面试之比赛积累、项目经验、个人未来发展
  3. 线上BUG定位神器(阿尔萨斯)-Arthas2019-0801
  4. 女生学高铁和计算机哪个更好,2020铁路最好的5个专业 女生上铁路学什么专业好...
  5. 数论四之综合训练——Magic Pairs,Crime Management,Top Secret,组合数问题
  6. 20个常用的正则表达式
  7. Stateflow中的事件执行顺序
  8. 【Java】快速排序,归并排序,堆排序
  9. python代码设置环境变量
  10. Swift 进阶 | 看得见的算法
  11. C++11更新内容(2)--完美转发--默认移动构造/移动赋值--1116
  12. (转)熊绎:我看软件工程师的职业规划
  13. 如果不能从做事转入治人,那么经年的螺丝钉岁月,会让你既无暇提高自己,也无法积累资源,在锈迹斑斑以后被新的螺丝钉换掉。
  14. excel下拉让函数参数部分不变
  15. 05、Python中转义字符与字符串
  16. 国家互联网信息办公室修订《互联网跟帖评论服务管理规定》发布施行
  17. vue实现列表的无缝滚动
  18. 指标管理是如何优化目标管理体系的!
  19. python处理文档对象【三方库—lxml】
  20. 2022 *CTF REVERSE的Simple File System

热门文章

  1. Mac更新系统后无法使用git
  2. teamview删除设备
  3. HM编码器代码阅读(16)——帧间预测之AMVP模式(四)预测MV的获取
  4. 创建一个Android Cardboard 360 Video Viewer
  5. 展示csdn的云服务
  6. maple java,讲解:MACM 401、Maple worksheet、Java,Python、Java,c++SQL|
  7. .Net Core 3.0 控制台 WebAPI 开发 基础环境搭建.
  8. 学习计算机软件技术感想,信息技术学习心得体会
  9. 制作ubuntu引导盘,到安装Ubuntu系统流程
  10. 龙芯与飞腾roadmap