zoukankan      html  css  js  c++  java
  • 【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

    Hint

    对于100%的数据,$1 leq N , M leq 10000000 $

    Solution

    由于((m!)|(n!)) 所以根据欧拉函数的性质,(n!)内与(m!)的数的个数为(Ans=frac {n!}{m!} varphi (m!))

    根据欧拉函数定义:(为的素因子varphi (N) = Nfrac{prod_{i=1}^k p_i-1}{prod_{i=1}^k p_i},p_i为N的素因子)

    (varphi(m!)=m!frac{prod_{i=1}^k p_i-1}{prod_{i=1}^k p_i})其中,(p_i)为不超过m的素数

    根据计算公式,有$$Ans=frac {n!}{m!} varphi (m!)=frac {n!}{m!} m!frac{prod_{i=1}^k p_i-1}{prod_{i=1}^k p_i} = n! frac{prod_{i=1}^k p_i-1}{prod_{i=1}^k p_i} $$

    维护3个信息,(i!),(prod_{i=1}^k p_i-1),((prod_{i=1}^k p_i-1)^{-1})即可O(1)回答询问。

    时间复杂度(O(max(n))).

    Code

    #include <stdio.h>
    #define MN 10000005
    #define R register
    #define ll long long
    #define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
    #define endfile fclose(stdin),fclose(stdout)
    inline int read(){
    	R int x; R bool f; R char c;
    	for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
    	for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
    	return f?-x:x;
    }
    int k[MN],inv[MN],pr[MN],fac[MN],n,m,T,p,pn;bool b[MN];
    inline void prework(){
    	k[1]=1;for (R int i=2; i<=1e7; ++i){
    		k[i]=(ll)k[i-1]*i%p;
    		if (!b[i]) pr[++pn]=i;
    		for (R int j=1; j<=pn&&(ll)pr[j]*i<=1e7; ++j){
    			b[i*pr[j]]=1;
    			if (i%pr[j]==0) break;
    		}
    	}inv[1]=1;for (R int i=2; i<=1e7; ++i){
    		if (i>=p) break;
    		inv[i]=(ll)(p-p/i)*inv[p%i]%p;
    	}fac[1]=1;for (R int i=2; i<=1e7; ++i){
    		fac[i]=fac[i-1];
    		if (!b[i]) fac[i]=(ll)fac[i]*(i-1)%p*inv[i%p]%p;
    	}
    }
    int main(){
    	T=read(),p=read();
    	prework();while(T--){
    		n=read(),m=read();
    		printf("%lld
    ",(ll)k[n]*fac[m]%p);
    	}
    }
    
  • 相关阅读:
    第1条:考虑用静态工厂方法代替构造器
    代理模式(Proxy Pattern)
    out 和 ref 参数修饰符
    SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈【转】
    Windows下获取Dump文件以及进程下各线程调用栈的方法总结(转)
    sql server内置函数
    ORA-16019 和 ORA-16018 错误的处理方法(转)
    marge into操作
    LogMiner配置使用手册
    课后作业
  • 原文地址:https://www.cnblogs.com/Melacau/p/bzoj2186.html
Copyright © 2011-2022 走看看