hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测
题意:
给你一个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素性检测的更多相关文章
- 2018 HDU多校第三场赛后补题
2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...
- hdu多校第三场
Problem D. Euler Function 思路:打表找找规律. #include<bits/stdc++.h> #define LL long long #define fi f ...
- HDU 多校 第三场 Find the answer
这题是原来cf上的一道原题,不过对于有一些数据范围修改了,不过还是很好想的 题意:给定一个长度为N的数组,对于数组中的每个位置,满足当前和小于M所需要去掉的最小代价 分析:对于当前是否需要进行去掉一些 ...
- HDU 多校 第三场 Fansblog
代码千万条,规范第一条 训练赛的时候打表找规律,发现答案是1/(st-pre-1)!,奈何用错了模板,一直TLE到比赛结束,一直以为是卡什么输入输出或者是两个素数相差太大导致复杂度过高,读入优化啥的都 ...
- hdu多校第七场 1006(hdu6651) Final Exam 博弈
题意: 有n道题,这n道题共m分,要求你至少做出k道才能及格,你可以自由安排复习时间,但是只有某道题复习时间严格大于题目分配的分值时这道题才能够被做出来,求最少的,能够保证及格的复习时间.复习时间和分 ...
- hdu多校第五场1006 (hdu6629) string matching Ex-KMP
题意: 给你一个暴力匹配字符串公共前缀后缀的程序,为你对于某个字符串,暴力匹配的次数是多少. 题解: 使用扩展kmp构造extend数组,在扩展kmp中,设原串S和模式串T. extend[i]表示T ...
- hdu多校第三场 1007 (hdu6609) Find the answer 线段树
题意: 给定一组数,共n个,第i次把第i个数扔进来,要求你删掉前i-1个数中的一些(不许删掉刚加进来这个数),使得前i个数相加的和小于m.问你对于每个i,最少需要删掉几个数字. 题解: 肯定是优先删大 ...
- HDU多校第三场 Hdu6606 Distribution of books 线段树优化DP
Hdu6606 Distribution of books 题意 把一段连续的数字分成k段,不能有空段且段和段之间不能有间隔,但是可以舍去一部分后缀数字,求\(min(max((\sum ai ))\ ...
- 2018 HDU多校第四场赛后补题
2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...
随机推荐
- 标准 IO 测试 标准输出,输入,出错缓冲大小;全缓冲文本流大小
例子:测试缓冲区大小 #include <stdio.h> int main(int argc, const char *argv[]) { //标准输入大小,没有输入内容时,标准输入缓冲 ...
- 从零开始搭建系统2.5——Apollo安装及配置
参见https://github.com/ctripcorp/apollo/wiki/Quick-Start安装即可
- 用C#简单实现的36进制转换代码
private const string initValue = "A0000001"; private static string cs = "0123456789AB ...
- 服务器搭建SVN
linux服务器搭建SVN https://blog.csdn.net/itbird58/article/details/80445521
- EasyUI - 简介
1. EasyUI : 简单的界面设计框架, 基于jQuery的UI插件, 主要用来设计网站的后台管理系统 2. EasyUI使用 : 将EasyUI提供的js文件和主题(themes)样式存放到项目 ...
- Java——包装类(Wrapper)
2.7包装类(Wrapper) 基本数据类型由于不是类,不能够使用java类库里提供的大量的方法.所有在设计上,我们让每一个基本数据类型都对应一个类,同时数据存储的范围还不变.此时相当于基本数据类型就 ...
- Java初识方法
5.初识方法 方法就是一段代码片段,这个片段可以完成特定的功能,并且可以重复利用. 5.1 方法的定义 5.1.1方法的定义格式 [方法修饰列表] 返回值类型 方法名(方法参数列表){ 方法体 } ① ...
- C++11中的技术剖析(std bind原理简单图解)
此文为转载,好像原出处的原文已经无法打开了. 本文解释了bind 是如何工作的.为了清晰,我对图中的语法作了一些简化(例如,省略函数调用操作符的参数类型),并且简化了 bind 的实现. bind 可 ...
- 关于rem单位的使用
rem在移动端应用可参考淘宝的页面http://m.taobao.com (html的font-size通过动态计算获取) 页面基准320px(20px),html font-size值的计算: 注: ...
- Delphi GDI(一)
Delphi 7下IGDIPlus库的使用 IGDI+是一个免费开源封装微软GDI+功能的Delphi库,该库使得可以用Delphi语言代码快速简短的实现复杂GDI+应用程序. 官方网站:http:/ ...