#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long int64;
int ca,top,prim[];
int64 A,B,K,pi,pk,ans,ti,q;
int64 ksm(int64 x,int64 y){
if (y==) return ;
if (y==) return x;
int64 d=ksm(x,y/);
if (y%==) return d*d*x;
else return d*d;
}
int64 exgcd(int64 a,int64 b,int64 &x,int64 &y){
if (b==){
x=,y=;
return a;
}
int64 temp=exgcd(b,a%b,x,y),tmp;
tmp=x,x=y,y=tmp-a/b*y;
return temp;
}
int64 YuanGen(int64 x){
bool flag;
top=;
int64 temp=x-;
for (int i=;i<=sqrt(x-);i++){
if (temp%i==){
prim[++top]=i;
while (temp%i==) temp/=i;
}
}
if (temp>) prim[++top]=temp;
for (int i=;;i++){
flag=;
for (int j=;j<=top;j++){
if (ksm(i,(x-)/prim[j])%x==){
flag=;
break;
}
}
if (flag) return i;
}
}
#define maxn 100005
#define maxm 400005
int now[maxn],prep[maxm];
int64 val[maxm];
void insert(int x,int64 y){
int64 pos=y%maxn;
prep[x]=now[pos],now[pos]=x,val[x]=y;
}
int find(int64 x){
int64 pos=x%maxn; int ans=maxm*;
for (int i=now[pos];i!=-;i=prep[i]){
if (val[i]==x) ans=min(ans,i);
}
if (ans==maxm*) return -;
else return ans;
}
int64 BSGS(int64 A,int64 B,int64 C){
memset(now,-,sizeof(now));
int64 pos,temp=ceil(sqrt(C*1.0)),D=,R=;
for (int i=;i<temp;i++){
insert(i,D);
D=D*A%C;
}
int64 tmp,x,y;
for (int i=;i<temp;i++){
tmp=exgcd(R,C,x,y);
x=(x*(B/tmp)%C+C)%C;
pos=find(x);
if (pos!=-) return i*temp+pos;
R=R*D%C;
}
return -;
}
int64 calc(int64 A,int64 B,int64 C){
q=YuanGen(pi);
int64 a,b,t,x,y,c=C-C/pi;
b=BSGS(q,B,C);
t=exgcd(A,c,x,y);
c/=t;
x=(x*(b/t)%c+c)%c;
int sum=;
for (int i=x;i<c*t;) sum++,i+=c;
return sum;
}
int64 work(int64 A,int64 B){
B%=pk; int64 a,b,c,x;
if (B==){
a=(ti-)/A+;
return pk/ksm(pi,a);
}
b=,c=;
while (B%pi==){
b++,c*=pi;
B/=pi;
}
if (b%A!=) return ;
x=b/A;
return calc(A,B,pk/c)*ksm(pi,b-x);
}
int main(){
int64 temp;
scanf("%d",&ca);
while (ca--){
scanf("%lld%lld%lld",&A,&B,&K);
K=K*+,temp=K; ans=;
for (int i=;i<=sqrt(K);i++){
if (temp%i==){
pi=i,pk=,ti=;
while (temp%i==){
pk*=i; ti++;
temp/=i;
}
ans*=work(A,B);
}
}
if (temp>){
pi=pk=temp; ti=;
ans*=work(A,B);
}
printf("%lld\n",ans);
}
return ;
}

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2219

题目大意:在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出满足 (1) X^A = B(mod 2*K + 1) (2) X 在范围[0, 2K] 内的X的个数!自然数论之神是可以瞬间秒杀此题的,那么你呢?

第一行有一个正整数T,表示接下来的数据的组数( T <= 1000) 之后对于每组数据,给出了3个整数A,B,K (1 <= A, B <= 10^9, 1 <= K <= 5 * 10^8)

输出一行,表示答案。

做法:这题很像之前写过的一个题,用原根+指标+bsgs即可,但是那一题B,C互质,且C一定存在原根。这题不一样了,设C=2*k+1,C不一定存在原根,但是我们可以将其标准分解,这些pi^ti一定存在原根,因为C%2==1,一定不会有2的幂,而奇素数的a次幂,a>=1,一定存在原根。我们对每个x^A=B(mod pi^ti)(0=<x<pi^ti)求出解的个数后乘起来就是原来的解,至于为什么,右转百度搜中国剩余定理推论。

怎么求x^A=B(mod pi^ti)(0=<x<pi^ti)的解的个数呢?我们将B%pi^ti,为了一些边界情况,我们要分情况讨论,当B=0时,那么x^A一定是pi^ti的倍数,我们x中存在因子p^a,且a*A>=ti,那么只要是p^a的倍数就行,可以手推式子。

当B>0时,我们将B分解为pi^b  * T,我们要想办法把pi^b约去,那么x^A中也要刚好有pi^b次方,否则之后同余不成立,所以当A不整除b时无解,令k=b/A,那么x=p^k  * G,G属于[0,p^(ti-k)),约去后化简为G^A = T (mod pi^(ti-b)),G属于[0,pi^(ti-b)),mod数存在原根,T与mod数互质,转化为了弱化版,可以用bsgs+原根求解,设解数为ans,最后应该ans*=p^(b-k),因为定义域缩小了,且存在大小为p^(ti-b)的循环节,除一下就知道最后要扩大的倍数了。

那么怎么求x^A=B(mod C)呢?  C存在原根,且(B,C)=1。我们找到C的原根g,找到B在原根g下modC的指标,x也必定为原根g的若干次方%C,式子变为

g^(aA)=g^b(mod C),由于循环节phi(C),变为aA=b(mod phi(C)),0=<a<phi(C),用扩展欧几里得算法即可实现。

bzoj2219: 数论之神的更多相关文章

  1. BZOJ2219数论之神——BSGS+中国剩余定理+原根与指标+欧拉定理+exgcd

    题目描述 在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出 ...

  2. BZOJ2219 数论之神 数论 中国剩余定理 原根 BSGS

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2219.html 题目传送门 - BZOJ2219 题意 求同余方程 $x^A\equiv B \pmo ...

  3. 【BZOJ】【2219】数论之神

    中国剩余定理+原根+扩展欧几里得+BSGS 题解:http://blog.csdn.net/regina8023/article/details/44863519 新技能get√: LL Get_yu ...

  4. 牛客国庆集训派对Day5 数论之神

    题目描述 终于活成了自己讨厌的样子. 这是她们都还没长大的时候发生的故事.那个时候,栗子米也不需要为了所谓的爱情苦恼. 她们可以在夏日的午后,花大把的时间去研究生活中一些琐碎而有趣的事情,比如数论. ...

  5. BZOJ 2219 数论之神 (CRT推论+BSGS+原根指标)

    看了Po神的题解一下子就懂了A了! 不过Po神的代码出锅了-solve中"d-temp"并没有什么用QwQQwQQwQ-应该把模数除以p^temp次方才行. 来自BZOJ讨论板的h ...

  6. BZOJ 2219: 数论之神

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2219 N次剩余+CRT... 就是各种奇怪的分类讨论.. #include<cstrin ...

  7. 10月wish me luck

    10/13 明天开始的三天 就要跟历史地理化学说拜拜了 以诚待之 好运 10/20 P三角形计数:一看就是叉积.因为去年迪子讲过.但是我已经忘记了.所以重新写了一遍.把所有的点有序化,将三角形面积转化 ...

  8. ZJOI2019游记

    Day-2 本蒟蒻有幸能去参加ZJOI2019,然而出发前就做好了爆0的准备. 坐了差不多6,7个小时的车,车上基本就是在颓知乎和打雀,然后就到了酒店. 招宝山酒店--本人住过的第一个四星级酒店,看上 ...

  9. hdu4048

    题意:给定m个数,还有n,n表示有一个长度为n的环,现在要求从M个数中选出若干个数,要求选出的数最大公约数为1,填充在n个位置中,选出的数可以重复,求多少种种方案.旋转当成一样的 . 思路:假设现在选 ...

随机推荐

  1. 表单 - Form - 无刷新提交原理

    为什么Form组件的表单提交可以做到无刷新? EasyUI在提交的时候,将表单作为一个隐藏的iframe进行的提交,并不是我们看到的那个表单进行的提交 并且那个iframe使用了绝对定位,保证页面上不 ...

  2. 005商城项目:ssm框架的整合成功之后的问题:使用maven的tomcat插件时的debug

    在执行maven的clean时经常碰到一个问题: 解决: 然后: 还有一个问题是:用maven 使用Debug调试时,不能看到源代码. 解决办法: 下面选择Debug Configurations 这 ...

  3. 从浏览器输入url到页面加载完成都发生了什么

    一个http请求的过程 简要介绍一下一个http请求的网络传输过程: DNS Lookup先获得URL对应的IP地址 Socket Connect浏览器和服务器建立TCP连接 Send Request ...

  4. ZooKeeper 笔记(4) 实战应用之【消除单点故障】

    关键节点的单点故障(Single Point of Failure)在大型的架构中,往往是致命的.比如:SOA架构中,服务注册中心(Server Register)统一调度所有服务,如果这个节点挂了, ...

  5. addShutdownHook的用法

    addShutdownHook作为一个正常关闭Java程序的途径,其实是非常有用的. 有JDK文档可知,当程序正常退出,或者为响应用户中断而终止虚拟机的时候,就会调用里面的线程,来作最后的退出处理. ...

  6. 【分布式协调器】Paxos的工程实现-cocklebur选举

    其实整个项目中一个最主要的看点就是选举算法,而这部分也是逻辑最复杂最难理解的部分.不同的实现在不同的场景下的策略也不尽相同,而且场景非常之多.接下来我们一起来看一下Cocklebur的实现思路. 一个 ...

  7. HDU5878~HDU5891 2016网络赛青岛

    A.题意:给出一个整数n, 找出一个大于等于n的最小整数m, 使得m的质因数只有2 3 5 7 分析:预处理出质因数2 3 5 7的数,超过maxt就行,然后找 B.题意:求1/1^2+1/2^2+. ...

  8. 25 uname-用于显示系统信息

    uname可显示电脑以及操作系统的相关信息. 语法 uname [-amnrsv][--help][--version] 参数说明: -a或--all 显示全部的信息. -m或--machine 显示 ...

  9. php 实现创建文件并追加数据

    最近因为后台有其他事情忙,所以我最近又开始学习php的内容了. (不过话说回来从客户端写到后台的感觉还是很爽的,嘿嘿) 需求是这样:从前台发来一些信息,存成文本文档,以后再统一处理(比如,存入用户账户 ...

  10. 使用iframe标签结合springMvc做文件上传

    1.iframe.jsp <body> <h1>测试iframe文件上传</h1> <!-- 1.要求表单的target属性名称与iframe的name名字一 ...