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

传送门

Problem 2186. – [Sdoi2008]沙拉公主的困惑

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

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 3058  Solved: 1040
[Submit][Status][Discuss]

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

解题思路:

首先我们需要知道的一个知识点就是:对于两个正整数n 和 m,如果 n 是 m 的倍数,那么 [1,n]

中与 m 互素的数的个数为 nm?phi(m)

那么现在在这个题中,让你求的是 [1,N!] 中与 M! (m≤n) 互素的个数,那么狠明显的是 N!

是 M! 的倍数,那么我们就可以运用刚才所说的知识点: 我们要求的结果就是 :

ans=N!M!?Phi(M!)

其中 Phi(M!) 的展开式就是 M!?(1?1p1)?(1?1p2)?..?(1?1pk), p1p2...pk都是

≤M 的素数,所以ans=N!?(1?1p1)?(1?1p2)?..?(1?1pk) 因为有除法,所以我们就

需要处理逆元问题了,但是正常处理的话会超时,所以我们就引出来了一个新的公式:

Inv[i]=(Mod?Modi)?Inv[Mod%i]%Mod

得到这个公式就行了,这个题目就可以完美解决了,首先我们预处理N! ,然后预处理逆元 Inv[i]

通过公式,其实最开始的时候不要忘记素数筛这样就行了。

My Code :

/**
2016 - 08 - 10 上午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 1e7+50;
const double eps = 1e-7;
const double PI = acos(-1.0);
using namespace std;
bitset <MAXN> prime;
bool isprime()
{
    prime.set();
    for(int i=2; i<MAXN; i++)
        if(prime[i])
            for(int j=i+i; j<MAXN; j+=i)
                prime[j] = false;
}
LL Inv[MAXN], fac[MAXN], ans[MAXN];
int main()
{
    isprime();
    LL R;
    int N, M, T;
    scanf("%d%lld",&T, &R);
    Inv[1] = 1;
    for(int i=2; i<MAXN; i++)
    {
        if(i >= R)
            break;
        Inv[i] = ( (R-R/i)*Inv[R%i] ) % R;
    }
    fac[0] = 1;
    for(int i=1; i<MAXN; i++)
        fac[i] = ( fac[i-1]*i ) % R;
    ans[1] = 1;
    for(int i=2; i<MAXN; i++)
    {
        if(prime[i])
        {
            ans[i] = ( ans[i-1]* (i-1) ) % R;
            ans[i] = ( ans[i] * Inv[i%R] ) % R;
        }
        else
            ans[i] = ans[i-1];
    }
    while(T--)
    {
        scanf("%d%d",&N,&M);
        printf("%lld\n",ans[M]*fac[N] % R);
    }
    return 0;
}
时间: 2024-10-11 01:40:30

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

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

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

数学(逆元):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]沙拉公主的困惑

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]沙拉公主的困惑(欧拉函数)

题目: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 沙拉公主的困惑 数论

题目大意:给定询问组数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