BZOJ2186 [Sdoi2008]沙拉公主的困惑
2017-10-25 08:04
330 查看
标签:逆元,筛法,数学,数论
Description
大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。
Input
第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n
Output
共T行,对于每一对N,M,输出1至N!中与M!素质的数的数量对R取模后的值
Sample Input
1 11
4 2
Sample Output
1
数据范围:
对于100%的数据,1 < =N , M < = 10000000
题意:求1àN!中与M!互质的个数
分析:我们要求的答案就是φ(m!)*(n!)/(m!)%p
有关答案的推导(http://blog.csdn.net/PoPoQQQ/article/details/39957117)
而φ(m!)=m!*(pi-1)/pi pi为m!的质因数
所以我们最后的结果就是n!*∏(pi-1)/pi
那么需要求1到1e7的素数和逆元
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define mem(x,num) memset(x,num,sizeof x)
using namespace std;
inline LL read()
{
LL f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int maxn=1e7+6;
LL ans[maxn],fac[maxn],inv[maxn],n,m,T,cnt=0,mod;
int prime[1000000];
bool not_prime[maxn];
void shaker()
{
LL j;
rep(i,2,maxn){
if(!not_prime[i])prime[++cnt]=i;
for(j=1;j<=cnt&&i*prime[j]<=maxn;j++){
not_prime[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
fac[1]=inv[1]=1;
rep(i,2,maxn)fac[i]=fac[i-1]*i%mod;
rep(i,2,maxn){
if(i==mod)break;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
ans[1]=1;
rep(i,2,maxn)
if(!not_prime[i])ans[i]=ans[i-1]*(i-1)%mod*inv[i%mod]%mod;
else ans[i]=ans[i-1];
}
int main()
{
T=read(),mod=read();
shaker();
while(T--)
{
n=read(),m=read();
printf("%lld\n",fac
*ans[m]%mod);
}
return 0;
}
Description
大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。
Input
第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n
Output
共T行,对于每一对N,M,输出1至N!中与M!素质的数的数量对R取模后的值
Sample Input
1 11
4 2
Sample Output
1
数据范围:
对于100%的数据,1 < =N , M < = 10000000
题意:求1àN!中与M!互质的个数
分析:我们要求的答案就是φ(m!)*(n!)/(m!)%p
有关答案的推导(http://blog.csdn.net/PoPoQQQ/article/details/39957117)
而φ(m!)=m!*(pi-1)/pi pi为m!的质因数
所以我们最后的结果就是n!*∏(pi-1)/pi
那么需要求1到1e7的素数和逆元
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define LL long long
#define mem(x,num) memset(x,num,sizeof x)
using namespace std;
inline LL read()
{
LL f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int maxn=1e7+6;
LL ans[maxn],fac[maxn],inv[maxn],n,m,T,cnt=0,mod;
int prime[1000000];
bool not_prime[maxn];
void shaker()
{
LL j;
rep(i,2,maxn){
if(!not_prime[i])prime[++cnt]=i;
for(j=1;j<=cnt&&i*prime[j]<=maxn;j++){
not_prime[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
fac[1]=inv[1]=1;
rep(i,2,maxn)fac[i]=fac[i-1]*i%mod;
rep(i,2,maxn){
if(i==mod)break;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
ans[1]=1;
rep(i,2,maxn)
if(!not_prime[i])ans[i]=ans[i-1]*(i-1)%mod*inv[i%mod]%mod;
else ans[i]=ans[i-1];
}
int main()
{
T=read(),mod=read();
shaker();
while(T--)
{
n=read(),m=read();
printf("%lld\n",fac
*ans[m]%mod);
}
return 0;
}
相关文章推荐
- 【bzoj 2186】: [Sdoi2008]沙拉公主的困惑
- 【BZOJ2186】【SDOI2008】沙拉公主的困惑
- BZOJ2186: [Sdoi2008]沙拉公主的困惑
- [bzoj2186] [Sdoi2008]沙拉公主的困惑
- BZOJ 2186: [Sdoi2008]沙拉公主的困惑
- bzoj2186【Sdoi2008】沙拉公主的困惑 数论:欧拉筛法,线性逆元
- BZOJ 2186-[Sdoi2008]沙拉公主的困惑(乘法逆元)
- BZOJ 2186 SDOI2008 沙拉公主的困惑 数论
- bzoj2186 [Sdoi2008]沙拉公主的困惑
- 【BZOJ 2186】 2186: [Sdoi2008]沙拉公主的困惑 (欧拉筛,线性求逆元)
- 【bzoj2186】【sdoi2008】【沙拉公主的困惑】【数论】
- BZOJ_2186_[Sdoi2008]沙拉公主的困惑_欧拉函数
- BZOJ 2186 [SDOI 2008]沙拉公主的困惑 简单数论
- Bzoj2186 [Sdoi2008]沙拉公主的困惑
- [BZOJ 2186][Sdoi2008]沙拉公主的困惑:欧拉函数
- bzoj2186【SDOI2008】沙拉公主的困惑
- [bzoj2186][Sdoi2008]沙拉公主的困惑——数论
- bzoj2186 [Sdoi2008]沙拉公主的困惑
- bzoj 2186 [Sdoi2008]沙拉公主的困惑(欧拉函数,逆元)
- BZOJ 2186: [Sdoi2008]沙拉公主的困惑| 数论