• bzoj2186 [Sdoi2008]沙拉公主的困惑


    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

    正解:欧拉函数+线性筛。

    比较基础的一道数论题,不过很卡常数。。

    首先,若$(x,y)=1$,根据欧几里得定理可得,$(x+y,y)=1$。

    那么在$m!$以内,与$m!$互质的数有$varphi (m!)$个,又因为$n!$肯定是$m!$的倍数,所以$Ans=varphi (m!)*frac{n!}{m!}$

    注意到$m!$的质因子为$leq m$的所有质数,于是$varphi (m!)=m!*prod frac{x-1}{x}$,其中$xleq m$且$x$为质数。

    所以$Ans=n!*prod frac{x-1}{x}$,那么现在就很简单了,预处理出逆元,阶乘,和连乘后面那一坨东西,然后直接带入算答案就行了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define N (10000010)
    14 #define inf (1<<30)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 ll phi[N],fac[N],inv[N],prime[N/5],n,m,p,cnt;
    23 bool vis[N];
    24 
    25 il ll gi(){
    26     RG ll x=0,q=1; RG char ch=getchar();
    27     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    28     if (ch=='-') q=-1,ch=getchar();
    29     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    30     return q*x;
    31 }
    32 
    33 il void pre(){
    34     fac[0]=fac[1]=inv[1]=phi[1]=1;
    35     for (RG ll i=2;i<N && i<p;++i) inv[i]=(p-p/i)*inv[p%i]%p;
    36     for (RG ll i=2;i<N;++i){
    37     fac[i]=fac[i-1]*i%p;
    38     if (!vis[i]) prime[++cnt]=i,phi[i]=(i-1)*inv[i%p]%p;
    39     if (!phi[i]) phi[i]=phi[i-1]; else (phi[i]*=phi[i-1])%=p;
    40     for (RG ll j=1,k;j<=cnt;++j){
    41         k=i*prime[j]; if (k>=N) break;
    42         vis[k]=1; if (!(i%prime[j])) break;
    43     }
    44     }
    45     return;
    46 }
    47 
    48 il void work(){
    49     n=gi(),m=gi();
    50     printf("%lld
    ",phi[m]*fac[n]%p); return;
    51 }
    52 
    53 int main(){
    54     File("princess");
    55     RG ll T=gi();
    56     p=gi(),pre();
    57     while (T--) work();
    58     return 0;
    59 }
  • 相关阅读:
    基本数据类型
    python IF while逻辑判断语句
    python文件的执行
    【ListBox】ListBox的相关操作
    C#基础-replace()过滤非法字符
    vmware虚拟机提示:无法将Ethernet0连接到虚拟网络vmnet02018-03-07
    linux 网卡配置文件详解2018-03-07
    eclipse+pydev 安装和配置过程
    Object与String
    P3369 【模板】普通平衡树(权值线段树)
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7000817.html
Copyright © 2020-2023  润新知