**
Fansblog(杭电多校第三场F题)
**
题目描述:
Farmer John keeps a website called ‘FansBlog’ .Everyday , there are many people visited this blog.One day, he find the visits has reached P , which is a prime number.He thinks it is a interesting fact.And he remembers that the visits had reached another prime number.He try to find out the largest prime number Q ( Q < P ) ,and get the answer of Q! Module P.But he is too busy to find out the answer. So he ask you for help. ( Q! is the product of all positive integers less than or equal to n: n! = n * (n-1) * (n-2) * (n-3) *… * 3 * 2 * 1 . For example, 4! = 4 * 3 * 2 * 1 = 24 )
输入:
First line contains an number T(1<=T<=10) indicating the number of testcases.
Then T line follows, each contains a positive prime number P (1e9≤p≤1e14)
输出:
For each testcase, output an integer representing the factorial of Q modulo P.
样例输入:
1
1000000007
样例输出:
328400734
题目大意:
给一个正整数素数p,求一个小于p的最大正整数素数q,输出 q的阶乘%p的结果(有多组输入)。
心路历程及题解:
前面看错题的丢人事就不说了,就从真正理解题意开始说起吧。。。求素数,我们一开始想的是用欧拉筛暴力打表,再把表暴力打进数组里,最后发现1e14的数据程序跑不出来。。。只能用了一个真.暴力解法(从p开始一个一个往前推,每个数跑1e7的数据,如果被卡掉就说明不是素数),当然这个做法比较玄学,只能说数据正好符合了吧。之后,我们采用了逆元的解法(逆元:a,p互质,则a/p=a**a^(p-2),这个怎么用的在文尾图中说明),又发现数据太大,long long都装不下,只好用了大数乘法(不是高精度)。。。这中间还有一个规律,p和q如果是孪生素数,结果是-1,当然对这题用处不大,最后把它去掉跑的时间一样。还是两个队友太强,我最后就是看懂他们的代码改了个bug。。。orz
AC代码:
#include <iostream>
#include <time.h>
#include <fstream>
using namespace std;
typedef unsigned long long ll;
ll mul(ll a,ll b,ll mod)//大数乘法,其实和快速幂就只有两处改动,已在下面标出
{
a%=mod;
b%=mod;
ll sum=0;
while(b)
{
if(b&1)
{
sum=(sum+a)%mod;//001,将*改为+
}
b>>=1;
a=a*2%mod;//002,将*a改为*2
}
sum%=mod;
return sum;
}
ll qmod(ll a,ll b,ll mod)//快速幂
{
ll sum=1;
while(b)
{
if(b&1)
{
sum=mul(sum,a,mod);
}
b>>=1;
a=mul(a,a,mod);
}
return sum;
}
ll getfac(ll s,ll e,ll mod)//这个是求分母,分母是什么文尾图片解释
{
ll f=1;
for(ll i=s+1; i<=e-2; i++)
{
f=mul(f,i,mod);
}
f%=mod;
return f;
}
bool judge(ll n)//判断素数
{
for(ll i=2; i<=10000000; i++)
{
if(n%i==0)
return false;
}
return true;
}
int main()
{
int T;
cin>>T;
while(T--)
{
ll n;
cin>>n;
ll p;
for(p=n-1; p; p--)
{
if(judge(p))
break;
}
if(p==n-2)//特判,要不要都行
{
cout<<1<<endl;
continue;
}
ll fac=getfac(p,n,n);
ll ans=qmod(fac,n-2,n)%n;//求逆元
cout<<ans<<endl;
}
return 0;
}
作者:suol,明灵
来源:CSDN
原文:https://blog.csdn.net/soul_mingling/article/details/97751852