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


    2186: [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

      

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <bitset> 
     5 using namespace std;
     6 const int N=10000000;
     7 int cnt,prime[N/10];
     8 int a1[N+10],a2[N+10],inv[N+10];
     9 bool check[N+10];
    10 void Shaker(){
    11     for(int i=2;i<=N;i++){
    12         if(!check[i])
    13             prime[++cnt]=i;
    14         for(int j=1;j<=cnt;j++){
    15             if(i*prime[j]>N)break;
    16             check[i*prime[j]]=true;
    17             if(i%prime[j]==0)break;        
    18         }    
    19     }            
    20 }
    21 int main(){
    22     int T,R,n,m;
    23     scanf("%d%d",&T,&R);
    24     Shaker();
    25     inv[1]=1;
    26     for(int i=2;i<=N&&i<R;i++)
    27         inv[i]=1ll*(R-R/i)*inv[R%i]%R;
    28     a1[0]=1;
    29     for(int i=1;i<=N;i++)
    30         a1[i]=1ll*a1[i-1]*i%R;
    31     a2[1]=1;
    32     for(int i=2;i<=N;i++)
    33         if(check[i])a2[i]=a2[i-1];
    34         else a2[i]=1ll*a2[i-1]*(i-1)%R*inv[i%R]%R;
    35     while(T--){
    36         scanf("%d%d",&n,&m);
    37         printf("%d
    ",1ll*a1[n]*a2[m]%R);
    38     }
    39     return 0;
    40 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    java反射——字段
    java反射——方法
    java反射——构造方法
    代构建高可用分布式系统的利器——Netty
    JavaEE复习计划
    Java基础复习计划(三)
    Java基础复习计划(二)
    Java基础复习计划
    关于内网穿透的相关内容
    Docker化你的应用
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5571123.html
Copyright © 2020-2023  润新知