题意:

给你一个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. 反编译字节码角度分析synchronized关键字的原理

    1.synchronized介绍 synchronized是java关键字.JVM规范中,synchronized关键字用于在线程并发执行时,保证同一时刻,只有一个线程可以执行某个代码块或方法:同时还 ...

  2. 了解GTIN小记

    GTIN为条形码,即"全球贸易项目代码"(Global Trade Item Number ) GTIN用作识别商品品项的全球性独一编码,是编码系统中应用最广泛的标识代码. GTI ...

  3. 快速失败and安全失败

    快速失败: 举个栗子: public static void main(String[] args) { ArrayList<String> list=new ArrayList<& ...

  4. leetcood学习笔记-141-环形列表

    题目描述: 方法一: class Solution(object): def hasCycle(self, head): """ :type head: ListNode ...

  5. [原创] delphi Memo 滚动到底部/开始 [Delphi XE、Delphi 7]

    以前控制Memo滚动到底部的操作: SendMessage(memo1.Handle,WM_VSCROLL,SB_BOTTOM,0); 或者 Memo1.SelLength:=Length(Memo1 ...

  6. Zookeeper_ZAB协议

    ZAB协议 ZAB协议简介 ZAB:(Zookeeper Atomic Broadcast),zk原子消息广播协议,是专为ZK设计的一中支持崩溃恢复的原子广播协议,是一种Paxos协议的优化算法,在Z ...

  7. Zookeeper的单机&集群环境搭建

    单机环境的安装 首先下载ZK的二进制安装包:http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/ 将安装包上传到Linux上: 进行解 ...

  8. IDEA使用的JDK版本1.9换成1.8后,在IDEA中需要改的配置

    今天上午上课spring5使用注解方式的时候,发现jdk9不兼容,果断换jdk8 步骤如下 一.查看Project中的jdk 1.检查Project SDK:中jdk 版本是否为1.8版本 2.检查P ...

  9. js基础用法 ,基础语法

    js用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 <body> 和 <head& ...

  10. django简单实现短url

    一.短url的原理 什么是短url: 简单讲就是把普通正常访问的网址,转换成比较短的网址,例如:https://www.cnblogs.com/angelyan/articles/10667354.h ...