zoukankan      html  css  js  c++  java
  • [BZOJ 2186][SDOI 2008] 莎拉公主的困惑

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

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 4519  Solved: 1560
    [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

    题解

    其实就是求 $varphi(m!) imes frac{n!}{m!}$

    无脑筛...

    给模数之后瞎**乱筛就行了...

    筛完素数推阶乘, 顺便再把 $varphi(i)/i$ 一块推出来...

    但是这题数据非常不清真: 题目保证 $R$ 为质数然而数据里有 $R$ 不是素数的情况...(详见BZOJ Discuss)...

    本来我用的是快速幂求逆元来推 $varphi(i)/i$ 然后WA到死...然后只能滚回去用 $ExGCD$ 了QAQ

    参考代码

    GitHub

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 const int MAXN=1e7+10;
     8 
     9 int p;
    10 int n;
    11 int m;
    12 int primen;
    13 int ans[MAXN];
    14 int fact[MAXN];
    15 int prime[MAXN];
    16 int inverse[MAXN];
    17 
    18 bool visited[MAXN];
    19 
    20 void ExGCD(int,int,int&,int&);
    21 void PreProcess();
    22 
    23 int main(){
    24     int t;
    25     scanf("%d%d",&t,&p);
    26     PreProcess();
    27     while(t--){
    28         scanf("%d%d",&n,&m);
    29         printf("%d
    ",1ll*fact[n]*ans[m]%p);
    30     }
    31     return 0;
    32 }
    33 
    34 void PreProcess(){
    35     int x,y;
    36     fact[1]=1;
    37     for(int i=2;i<MAXN;i++){
    38         fact[i]=1ll*fact[i-1]*i%p;
    39     }
    40     inverse[1]=1;
    41     for(int i=2;i<MAXN;i++){
    42         if(!visited[i]){
    43             ExGCD(i,p,x,y);
    44             inverse[i]=(x%p+p)%p;
    45             for(int j=i+i;j<MAXN&&j>0;j+=i){
    46                 visited[j]=true;
    47             }
    48         }
    49     }
    50     ans[1]=1;
    51     for(int i=2;i<MAXN;i++){
    52         ans[i]=ans[i-1];
    53         if(!visited[i])
    54             ans[i]=1ll*ans[i]*(i-1)%p*inverse[i]%p;
    55     }
    56 }
    57 
    58 void ExGCD(int a,int b,int& x,int& y){
    59     if(b==0){
    60         x=1;
    61         y=0;
    62         return;
    63     }
    64     else{
    65         ExGCD(b,a%b,x,y);
    66         int tmp=x;
    67         x=y;
    68         y=tmp-a/b*y;
    69     }
    70 }
    Backup

  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/rvalue/p/7360163.html
Copyright © 2011-2022 走看看