1038 X^A Mod P

基准时间限制:1 秒 空间限制:131072 KB 分值: 320
X^A mod P = B,其中P为质数。给出P和A B,求< P的所有X。

例如:P = 11,A = 3,B = 5。
3^3 Mod 11 = 5
所有数据中,解的数量不超过Sqrt(P)。
 
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100)
第2 - T + 1行:每行3个数P A B,中间用空格隔开。(1 <= A, B < P <= 10^9, P为质数)
Output
共T行,每行包括符合条件的X,且0 <= X < P,如果有多个,按照升序排列,中间用空格隔开。如果没有符合条件的X,输出:No Solution。所有数据中,解的数量不超过Sqrt(P)。
Input示例
3
11 3 5
13 3 1
13 2 2
Output示例
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的更多相关文章

  1. 解高次同余方程 (A^x=B(mod C),0<=x<C)Baby Step Giant Step算法

    先给出我所参考的两个链接: http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 (AC神,数论帝  扩展Baby Step Gian ...

  2. 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 ...

  3. 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)

    什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...

  4. 『高次同余方程 Baby Step Giant Step算法』

    高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...

  5. 高次同余方程模板BabyStep-GiantStep

    /************************************* ---高次同余方程模板BabyStep-GiantStep--- 输入:对于方程A^x=B(mod C),调用BabySt ...

  6. ACM_高次同余方程

    /*poj 3243 *解决高次同余方程的应用,已知 X^Y = K mod Z, 及X,Z,K的值,求 Y 的值 */ #include<cstdio> #include<cstr ...

  7. 扩展欧几里得,解线性同余方程 逆元 poj1845

    定理:对于任意整数a,b存在一堆整数x,y,满足ax+by=gcd(a,b) int exgcd(int a,int b,int &x,int &y){ ){x=,y=;return ...

  8. 求同余方程x^A=B(mod m)的解个数(原根与指标)

    求方程:的解个数 分析:设,那么上述方程解的个数就与同余方程组:的解等价. 设同于方程的解分别是:,那么原方程的解的个数就是 所以现在的关键问题是求方程:的解个数. 这个方程我们需要分3类讨论: 第一 ...

  9. 51Nod1038 X^A Mod P 数论 原根 BSGS

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1038.html 题目传送门 - 51Nod1038 题意 题解 在模质数意义下,求高次剩余,模板题. ...

随机推荐

  1. centos/linux下的安装git

    1.下载git wget https://github.com/git/git/archive/v2.14.1.zip 2.安装依赖 sudo yum -y install zlib-devel op ...

  2. 通过js区分移动端浏览器(微信浏览器、QQ浏览器、QQ内置浏览器)

    由于公司业务中涉及到一个分享指引功能,而像微信.QQ内置浏览器需要引导用户点击右上角进行操作,其他浏览器则引导点击浏览器下方进行操作,因此需要区分浏览器类型: 通过在页面alert(navigator ...

  3. CentOS7上LNMP安装包一步搭建LNMP环境

    系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian Linux系统 需要5GB以上硬盘剩余空间 需要128MB以上内存(如果为128MB的小内存VPS,Xe ...

  4. C#中ASCII码学习心得

    1.利用调用ASCIIEncoding类来实现各种转换.如简单个ACS码和int转换. ***利用(int)ASCIIEncoding类对象.GetBytes(character)[0]得到整数: p ...

  5. jsp去除空行的web.xml配置

    在jsp中我们引入的标签,例如jstl的标签,循环遍历等等,可能会产生很多空行,其实也没什么,不会影响展示,但是空行多多少少会影响性能,这是我们只需要在web.xml中配置一下我们就可以很简单的去掉, ...

  6. 获得某个月的天数(java, mysql, oracle)

    java方式: Calendar   cal   =   Calendar.getInstance(); cal.set(Calendar.YEAR,year); cal.set(Calendar.M ...

  7. python介绍篇

    二进制编码ASSIC 每一个字符统一都需要8个bit来存储 计算机容量 1位 = 1bit 8bit = 1byte = 1字节 1024bytes = 1kbytes =1KB 1024个字符,小文 ...

  8. Jenkins构建Android项目持续集成之findbugs的使用

    Findbugs简介 关于findbugs的介绍,可以自行百度下,这里贴下百度百科的介绍.findbugs是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题 ...

  9. memcache 中的add set 和replace的区别

    用过memcache的人都有一个疑惑,那就是memcache中为什么会有一个add方法.一个set方法.一个replace呢,这几个方法又有着什么样的区别呢,下边我们来分析下这几个方法的不同之处: m ...

  10. PL/SQL NOCOPY限制模式

    NOCOPY模式用于限定OUT模式和IN OUT模式在调用时是不是以传引用的方式进行. 默认情况下,OUT模式和IN OUT模式的参数是以传值的方式进行调用的. IN模式总是以传引用的方式,如果用NO ...