bzoj 2186 [Sdoi2008]沙拉公主的困惑 欧拉函数

bzoj 2186 [Sdoi2008]沙拉公主的困惑

题意:

大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。

限制:

数据组数T:1 <= T <= 10000

R <= 1e9+10

1 <= N,M <=10000000

思路:

首先答案为:

phi(m!)*n!/m!

证明过程如下:

gcd(a,b)=1 <=> gcd(a+b,b)=1

phi(m!)表示小于m!且与m!互质的数的个数,

不妨令它们为p[1],p[2],p[3],...,p[k],则有gcd(p[i],m!)=1,其中1 <= i <= k,

则有gcd(p[i]+m!,m!)=1,

所以最后答案为phi(m!)*n!/m!

然后问题落在phi(m!)的求法上面,

对于欧拉函数有公式:

phi(x)=x * (p[1] - 1)/p[1] * (p[2] - 1)/p[2] * ... * (p[k] - 1)/p[k],其中p[i] (1 <= i <= k) 为x的质因子

所以,求一遍m!的质因子即可,即为1~m内的素数。

/*bzoj 2186 [Sdoi2008]沙拉公主的困惑
  题意:
  大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。
  限制:
  数据组数T:1 <= T <= 10000
  R <= 1e9+10
  1 <= N,M <=10000000
  思路:
  首先答案为:
  phi(m!)*n!/m!
  证明过程如下:
  gcd(a,b)=1 <=> gcd(a+b,b)=1
  phi(m!)表示小于m!且与m!互质的数的个数,
  不妨令它们为p[1],p[2],p[3],...,p[k],则有gcd(p[i],m!)=1,其中1 <= i <= k,
  则有gcd(p[i]+m!,m!)=1,
  所以最后答案为phi(m!)*n!/m!

  然后问题落在phi(m!)的求法上面,
  对于欧拉函数有公式:
  phi(x)=x * (p[1] - 1)/p[1] * (p[2] - 1)/p[2] * ... * (p[k] - 1)/p[k],其中p[i] (1 <= i <= k) 为x的质因子
  所以,求一遍m!的质因子即可,即为1~m内的素数。
 */
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
const int N=1e7+5;
LL fac[N];

LL ext_gcd(LL a,LL b,LL &x,LL &y){
    if(b==0) { x=1, y=0; return a; }
    LL ret= ext_gcd(b,a%b,y,x);
    y-= a/b*x;
    return ret;
}

//要求a与m互质
LL inv(LL a,int m){   //求逆元
    LL d,x,y,t= (LL)m;
    d= ext_gcd(a,t,x,y);
    if(d==1) return (x%t+t)%t;
    return -1;
}

bool is_pri[N];
//int pri[N], tot;
void get_pri(int n){
	//tot = 0;
	memset(is_pri, 1, sizeof(is_pri));
	is_pri[0] = is_pri[1] = 0;
	for(int i = 2; i <= n; ++i)
		if(is_pri[i]){
			if(n / i < i) break;
			for(int j = i * i; j <= n; j += i) is_pri[j] = false;
		}
	//for(int i = 2; i <= n; ++i) if(is_pri[i]) pri[tot++] = i;
}

LL ans[N];

void predo(int mod){
	fac[0]=1;
	for(int i=1;i<N;++i){
		fac[i]=fac[i-1]*i%mod;
	}
	get_pri(N-1);
	ans[0]=1;
	for(int i=1;i<N;++i){
		ans[i]=ans[i-1];
		if(is_pri[i]) ans[i]=ans[i]*(i-1)%mod*inv(i,mod)%mod;
	}
}

void gao(int n,int m,int mod){
	printf("%lld\n",ans[m]*fac[n]%mod);
}

int main(){
	int T,R;
	scanf("%d%d",&T,&R);
	predo(R);
	while(T--){
		int n,m;
		scanf("%d%d",&n,&m);
		gao(n,m,R);
	}
	return 0;
}

时间: 2024-10-26 19:34:42

bzoj 2186 [Sdoi2008]沙拉公主的困惑 欧拉函数的相关文章

[BZOJ 2186][Sdoi2008]沙拉公主的困惑(欧拉函数)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2186 分析: 就是要求1~n!中与m!互质的数的个数 首先m!以内的就是φ(m!) 关键是m!~n!中的如何处理 首先要知道一个性质:gcd(a+b,b)=gcd(b,(a+b)%b)=gcd(b,a)=gcd(a,b) 即对于m!内所有与m!互质的数,只要给他们加上m!则也与m!互质且在(m!,n!]范围中,这样对于每个来说则有n!/m!个 所以ans=φ(m!)*(n!/m!)

数学(逆元):BZOJ 2186: [Sdoi2008]沙拉公主的困惑

2186: [Sdoi2008]沙拉公主的困惑 Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一 大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可. R是一个质数. Input 第一行为两个整数T,R.R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行

BZOJ 2186: [Sdoi2008]沙拉公主的困惑 (逆元的应用)

传送门 Problem 2186. – [Sdoi2008]沙拉公主的困惑 2186: [Sdoi2008]沙拉公主的困惑 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3058  Solved: 1040[Submit][Status][Discuss] Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大

BZOJ 2186 [Sdoi2008]沙拉公主的困惑

Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可.R是一个质数. Input 第一行为两个整数T,R.R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n Outp

[BZOJ 2186] [Sdoi2008] 沙拉公主的困惑 【欧拉函数】

题目链接:BZOJ - 2186 题目分析 题目要求出 [1, n!] 中有多少数与 m! 互质.(m <= n) 那么在 [1, m!] 中有 phi(m!) 个数与 m! 互质,如果一个数 x 与 m! 互质,即 gcd(m!, x) = 1, 那么 gcd(m!, m! + x) = 1, gcd(m!, m! * 2 + x) = 1, 即 x + k * m! 都与 m! 互质. 这样就很明确了,[1, n!] 中与 m! 互质的数有 phi(m!) * n! / m! 个. 怎么求

BZOJ 2186 SDOI2008 沙拉公主的困惑 数论

题目大意:给定询问组数T和取模数P,每次询问给定两个整数n和m,求1~(n!)的数中与m!互质的数个个数模P (m<=n) 首先T<=1W,暴力肯定过不去,我们须要预处理一些东西 首先我们知道,若x与y互质,则x+y与y也互质,x+2y与y也互质... 换到这道题上来说,若一个数x与m!互质,那么x+(m!)也一定与m!互质,(x+m!*2)也一定与m!互质... 因为n!一定是m!的倍数,于是我们每存在到一个x<=m!与m!互质,我们就一定能找到(n!)/(m!)个与m!互质的数 而m

BZOJ 2186 [Sdoi2008]沙拉公主的困惑 【逆元】

题意:求中互质的数的个数,其中. 分析:因为,所以,我们很容易知道如下结论    对于两个正整数和,如果是的倍数,那么中与互素的数的个数为      本结论是很好证明的,因为中与互素的个数为,又知道,所以 结论成立.那么对于本题,答案就是 事实上只要把素数的逆元用exgcd求一求就好,其余并未用到 逆元递推法: #include<stdio.h> #include<string.h> const int N=1e7+112; typedef long long ll; int pr

BZOJ 2186 [Sdoi2008]沙拉公主的困惑 线性逆元

题意:链接 方法:线性筛逆元 解析: SB卡常数题 不想多说什么正常人都会做 ans=?(m!)?n!m! ans=m!?n!m!?∏Pi?1Pi(Pi|m!) ans=n!?∏Pi?1Pi(Pi|m!) ans=n!?∏((Pi?1)?inv[Pi]) 代码: #include<cstdio> #include<cmath> #include<ctime> #include<cstring> #include<iostream> #includ

2186: [Sdoi2008]沙拉公主的困惑 - BZOJ

Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票.房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量.现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可.R是一个质数. Input 第一行为两个整数T,R.R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n Outp