题意:

给你一个1e9-1e14的质数P,让你找出这个质数的前一个质数Q,然后计算Q!mod P

题解:

1e14的数据范围pass掉一切素数筛法,考虑Miller-Rabin算法。

米勒拉宾算法是一种判断素数的随机化算法,由于其随机性,它不能保证总是正确的,但其对于一个素数,总会返回素数的结果,对于一个合数,才有极小概率返回素数的结果(假阳性)。

米勒拉宾算法对于单个素数的判断时间复杂度为$O(log^3n)$.(因为1e14相乘会爆longlong,模乘要写成龟速乘,因此要多一个log)

1849年,高斯猜想,素数分布密度符合如下的公式,$\pi(x) \approx x/lnx$,其中$\pi(x)$为不超过x的素数个数,根据这个公式,1e14以内,两个素数间隔平均只有46个左右,相当稠密了。

因此,只需要用米勒拉宾算法从P-1一个一个判断,直到找到另一个素数Q。

再给出一个结论,对于任意素数n,(n-2)! mod n = 1,因为从2到n-2,互为模n逆元的数捉对出现,证明可参考离散数学课本数论部分。

因此,计算Q! mod P只需计算 $\prod^{P-2}_{i=Q+1}i$ 再利用费马小定理快速幂求逆元即可。

需要注意,1e14相乘会爆longlong,可以用_int128,但稳妥一点的方法是用思想类似于快速幂的龟速乘。

#include<bits/stdc++.h>
#define Times 10
#define LL long long
#define ll long long
using namespace std; ll multi(ll a, ll b, ll m) {
ll ans = ; a %= m;
while (b) {
if (b & )ans = (ans + a) % m;
a = (a + a) % m; b >>= ;
} return ans;
} ll quick_mod(ll a, ll b, ll m) {
ll ans = ; a %= m;
while (b) {
if (b & )ans = multi(ans, a, m);
a = multi(a, a, m); b >>= ;
} return ans;
} bool Miller_Rabin(ll n) {
if (n == )return true;
if ((n < ) || !(n & ))return false;
ll m = n - ;
ll k = ;
while ((m & ) == ) {
k++; m >>= ;
}
for (ll i = ; i < Times; i++) {
ll a = rand() % (n - ) + ;
ll x = quick_mod(a, m, n);
ll y = ;
for (ll j = ; j < k; j++) {
y = multi(x, x, n);
if (y == && x != && x != n - )return false;
x = y;
} if (y != )return false;
} return true;
} long long quick_mul(long long x,long long y,long long mod)
{
long long ans=;
while(y!=){
if(y&==)ans+=x,ans%=mod;
x=x+x,x%=mod;
y>>=;
}
return ans;
}
long long quick_pow(long long x,long long y,long long mod)
{
long long sum=;
while(y!=){
if(y&==)sum=quick_mul(sum,x,mod),sum%=mod;
x=quick_mul(x,x,mod),x%=mod;
y=y>>;
}
return sum;
} int main(){
// LL pp=1;
// for(int i=1;i<=999999937;i++){
// pp=pp*i%1000000007;
// }
// printf("%lld\n",pp);
int t;
scanf("%d",&t);
while(t--){
LL q;
scanf("%lld",&q);
LL p;
for(register LL i=q-;;i-=){
if(Miller_Rabin(i)){
p=i;break;
}
}
// printf("%d\n",p);
LL ans=; for(LL j=p+;j<=q-;j++){
ans=quick_mul(ans,j,q);
}
printf("%lld\n",quick_pow(ans,q-,q));
}
return ;
}

hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测的更多相关文章

  1. 2018 HDU多校第三场赛后补题

    2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...

  2. hdu多校第三场

    Problem D. Euler Function 思路:打表找找规律. #include<bits/stdc++.h> #define LL long long #define fi f ...

  3. HDU 多校 第三场 Find the answer

    这题是原来cf上的一道原题,不过对于有一些数据范围修改了,不过还是很好想的 题意:给定一个长度为N的数组,对于数组中的每个位置,满足当前和小于M所需要去掉的最小代价 分析:对于当前是否需要进行去掉一些 ...

  4. HDU 多校 第三场 Fansblog

    代码千万条,规范第一条 训练赛的时候打表找规律,发现答案是1/(st-pre-1)!,奈何用错了模板,一直TLE到比赛结束,一直以为是卡什么输入输出或者是两个素数相差太大导致复杂度过高,读入优化啥的都 ...

  5. hdu多校第七场 1006(hdu6651) Final Exam 博弈

    题意: 有n道题,这n道题共m分,要求你至少做出k道才能及格,你可以自由安排复习时间,但是只有某道题复习时间严格大于题目分配的分值时这道题才能够被做出来,求最少的,能够保证及格的复习时间.复习时间和分 ...

  6. hdu多校第五场1006 (hdu6629) string matching Ex-KMP

    题意: 给你一个暴力匹配字符串公共前缀后缀的程序,为你对于某个字符串,暴力匹配的次数是多少. 题解: 使用扩展kmp构造extend数组,在扩展kmp中,设原串S和模式串T. extend[i]表示T ...

  7. hdu多校第三场 1007 (hdu6609) Find the answer 线段树

    题意: 给定一组数,共n个,第i次把第i个数扔进来,要求你删掉前i-1个数中的一些(不许删掉刚加进来这个数),使得前i个数相加的和小于m.问你对于每个i,最少需要删掉几个数字. 题解: 肯定是优先删大 ...

  8. HDU多校第三场 Hdu6606 Distribution of books 线段树优化DP

    Hdu6606 Distribution of books 题意 把一段连续的数字分成k段,不能有空段且段和段之间不能有间隔,但是可以舍去一部分后缀数字,求\(min(max((\sum ai ))\ ...

  9. 2018 HDU多校第四场赛后补题

    2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...

随机推荐

  1. 加载ubuntu的时候卡在‘SMBus Host Controller not enabled'错误

    实验系统:ubuntu-16.04.6-server-amd64 我在VMware安装完这个系统后进入发现卡在了’SMBus Host Controller not enabled‘里,后来查过网络发 ...

  2. 5. java运算符

    1.算术运算符 注意: % 取余数 (1)自增 (++)前自增:先自增完毕,再运算整个表达式,语句分号前面的都是运算表达式: 后自增,先运算完整个表达式(分号前面的都是表达式),再进行自增: 2.赋值 ...

  3. Java 基础 - JDK 和 JRE 有什么区别

    总结 JRE(Java Runtime Environment),就是 Java 运行环境,包括JVM虚拟机(java.exe等)和基本的类库(rt.jar等). JDK (Java Developm ...

  4. Java Swing 窗体屏幕居中

    Java开发桌面程序用AWT或SWING,可以用设置主窗口位置,使主窗口居中一般使用下面的方法: 01.第一种方法              int windowWidth = frame.getWi ...

  5. 小程序生成海报:通过 json 配置方式轻松制作一张海报图

    背景 由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 Canvas 功能生成一张带有二维码的图片,然后引导用户下载图片到本地后再分享到朋友圈.而小程序 ...

  6. NOIp2018集训test-9-15(联考二day1)

    T1.矩阵游戏 水题.每一行最后乘的数为x[i],每一列为y[i],暴力算第一行的列的贡献,每一行的列的贡献是公差为所有列的贡献之和的等差数列,然后每一行再乘上行的贡献求和即为答案. //Achen ...

  7. CommandLineToArgvW调EXE传入参数【转载】

    #include <afxwin.h>  // TODO: add your code here LPWSTR *szArglist = NULL; ; szArglist = Comma ...

  8. nginx+keepalive 实现高可用负载均衡方案

    转:http://ju.outofmemory.cn/entry/52165 主nginx负载均衡器:172.26.11.99  (通过keepalived配置了VIP:172.26.11.101供外 ...

  9. C++之内存分区

  10. iBATIS存储过程

    使用iBATIS配置来调用存储过程.为了理解这一章,首先需要了解我们是如何在MySQL中创建一个存储过程. 在继续对本章学习之前,可以通过MySQL存储过程. 我们已经在MySQL下有EMPLOYEE ...