【解高次同余方程】51nod1038 X^A Mod P
1038 X^A Mod P
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100)
第2 - T + 1行:每行3个数P A B,中间用空格隔开。(1 <= A, B < P <= 10^9, P为质数)
共T行,每行包括符合条件的X,且0 <= X < P,如果有多个,按照升序排列,中间用空格隔开。如果没有符合条件的X,输出:No Solution。所有数据中,解的数量不超过Sqrt(P)。
3
11 3 5
13 3 1
13 2 2
3
1 3 9
No Solution
题解
解高次同余方程时,先求出来原根
再用原根代换方程两边(要用到BSGS)
转化成一次剩余问题用EX_GCD求解即可
P.S. BSGS用map会T,所以我恬不知耻地贴了一份
代码
//by 减维
#include<set>
#include<map>
#include<queue>
#include<ctime>
#include<cmath>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define il inline
#define rg register
#define db double
#define mpr make_pair
#define maxn 100005
#define inf (1<<30)
#define eps 1e-8
#define pi 3.1415926535897932384626L
using namespace std; inline int read()
{
int ret=;bool fla=;char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-'){fla=;ch=getchar();}
while(ch>=''&&ch<=''){ret=ret*+ch-'';ch=getchar();}
return fla?-ret:ret;
} int t,num,cnt;
ll a,p,b,g,phip,pri[maxn],ans[maxn];
vector<ll> phipri;
map<ll,ll> mp;
bool pd[maxn]; il ll ksm(ll x,ll y,ll mod)
{
ll ret=;x%=mod;
for(;y;y>>=,x=x*x%mod)
if(y&) ret=ret*x%mod;
return ret;
} ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==){x=;y=;return a;}
ll gcd=exgcd(b,a%b,y,x);
y-=a/b*x;
return gcd;
} il void pre()
{
for(int i=;i<=maxn-;++i)
{
if(!pd[i]) pri[++num]=i;
for(int j=;j<=num&&i*pri[j]<=maxn-;++j)
{
pd[i*pri[j]]=;
if(i%pri[j]==) break;
}
}
} il ll getphi(ll x)
{
ll ret=x;
for(int i=;pri[i]*pri[i]<=x;++i)
if(x%pri[i]==)
{
ret=ret/pri[i]*(pri[i]-);
while(x%pri[i]==) x/=pri[i];
}
if(x>) ret=ret/x*(x-);
return ret;
} il bool check(ll g,ll x,ll p)
{
int siz=phipri.size();
for(int i=;i<siz;++i)
if(ksm(g,x/phipri[i],p)==) return ;
return ;
} il ll getg(ll x,ll p)
{
ll tmp=x;
phipri.clear();
for(int i=;i*i<=x;++i)
if(x%i==)
{
phipri.push_back(i);//printf("%lld ",pri[i]);
while(x%i==) x/=i;
}
if(x!=) phipri.push_back(x);//,printf("%lld ",x);
//puts("");
x=tmp;
ll gen=;
while()
{
if(check(gen,x,p)) return gen;
gen++;
}
} struct sa{
long long x;
int id;
bool operator<(const sa &b)const{
if (x == b.x) return id < b.id;
return x<b.x;
}
}rec[];
//用rec存离散对数
long long bsgs(long long x,long long n,long long m){
int s=(int)(sqrt((double)m+0.5));
while((long long)s*s<=m)s++;
long long cur=;
sa tmp;
for(int i=;i<s;i++){
tmp.x=cur,tmp.id=i;
rec[i]=tmp;
cur=cur*x%m;
}
sort(rec,rec+s);
//这里不能用map查找比较慢,采用排序二分就快了
long long mul= ksm(cur, m - , m) % m;
//这里有的方法是在下面的循环里求解快速幂,但本题是不行的 要在循环外面弄,保证时间
cur=; for(long long i=;i<s;i++){
long long more=n*cur%m;
tmp.x=more,tmp.id=-;
int j=lower_bound(rec,rec+s,tmp)-rec;
if(rec[j].x==more){
return i*s+rec[j].id;
}
cur=cur*mul%m;
}
return -;
} int main()
{
t=read();
pre();
while(t--){
p=read(),a=read(),b=read();
phip=p-;cnt=;
g=getg(phip,p);
//printf("%lld ",g);
ll c=bsgs(g,b,p);
//printf("%lld ",c);
if(c==-){puts("No Solution");continue;}
ll x,y;
ll gcd=exgcd(a,phip,x,y);
//printf("%lld ",gcd);
if(c%gcd!=){puts("No Solution");continue;}
x=x*(c/gcd)%phip;
ll delt=phip/gcd;
for(int i=;i<gcd;++i)
{
x=((x+delt)%phip+phip)%phip;
ans[++cnt]=ksm(g,x,p);
}
sort(ans+,ans+cnt+);
for(int i=;i<=cnt;++i) printf("%lld ",ans[i]);puts("");
}
return ;
}
【解高次同余方程】51nod1038 X^A Mod P的更多相关文章
- 解高次同余方程 (A^x=B(mod C),0<=x<C)Baby Step Giant Step算法
先给出我所参考的两个链接: http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 (AC神,数论帝 扩展Baby Step Gian ...
- POJ 3243 Clever Y (求解高次同余方程A^x=B(mod C) Baby Step Giant Step算法)
不理解Baby Step Giant Step算法,请戳: http://www.cnblogs.com/chenxiwenruo/p/3554885.html #include <iostre ...
- 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)
什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...
- 『高次同余方程 Baby Step Giant Step算法』
高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
- 高次同余方程模板BabyStep-GiantStep
/************************************* ---高次同余方程模板BabyStep-GiantStep--- 输入:对于方程A^x=B(mod C),调用BabySt ...
- ACM_高次同余方程
/*poj 3243 *解决高次同余方程的应用,已知 X^Y = K mod Z, 及X,Z,K的值,求 Y 的值 */ #include<cstdio> #include<cstr ...
- 扩展欧几里得,解线性同余方程 逆元 poj1845
定理:对于任意整数a,b存在一堆整数x,y,满足ax+by=gcd(a,b) int exgcd(int a,int b,int &x,int &y){ ){x=,y=;return ...
- 求同余方程x^A=B(mod m)的解个数(原根与指标)
求方程:的解个数 分析:设,那么上述方程解的个数就与同余方程组:的解等价. 设同于方程的解分别是:,那么原方程的解的个数就是 所以现在的关键问题是求方程:的解个数. 这个方程我们需要分3类讨论: 第一 ...
- 51Nod1038 X^A Mod P 数论 原根 BSGS
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1038.html 题目传送门 - 51Nod1038 题意 题解 在模质数意义下,求高次剩余,模板题. ...
随机推荐
- Yii小部件
小部件 Yii提供了一套数据小部件widgets,这些小部件可以用于显示数据. DetailView小部件用于显示一条记录数据. ListView和GridView小部件能够用于显示一个拥有分页.排序 ...
- Qt ActiveX web dome 详细例子
http://doc.qt.io/qt-5.9/activeqt-server.html hierarchy 例子 #ifndef OBJECTS_H #define OBJECTS_H #inclu ...
- uva10003 区间DP
很清晰的区间dp问题.d(i,j)表示断点i到断点j的最小费用,由于开头和结尾也是断点,所以应该加入断点数组,即 cut[0]=0; cut[n+1]=len; 边界就是d(i,i+1)=0; 转移方 ...
- 【BZOJ3993】 星际战争
Time Limit: 1000 ms Memory Limit: 128 MB Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一 ...
- hbase 命令
HBase是Google Bigtable的开源实现,它利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为协同服 ...
- csrf
什么是CSRF: CSRF(Cross-site request forgery),中文名称:跨站请求伪造 攻击者盗用了你的身份,以你的名义发送恶意请求.CSRF能够做的事情包括:以你名义发送邮件,发 ...
- Http协议规范及格式
HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616.HTTP协议采用了请求/响应模型.客户 ...
- python 循环语句 函数 模块
python循环语句 while循环语法结构 当需要语句不断的重复执行时,可以使用while循环 while expression: while_suite 语句ehile_suite会被连续不断的循 ...
- MyBatis框架概述
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动.创建connection.创建statement.手动设 ...
- JavaScript常用对象有哪些
JavaScript常用对象有哪些 1.String 2.Date 3.Math 4.Array 5.Number 6.Boolean