zoukankan      html  css  js  c++  java
  • [BZOJ2186]沙拉公主的困惑

    [BZOJ2186]沙拉公主的困惑

    题面

    大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为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 11luog
    4 2

    Sample Output

    1

    数据范围: 对于100%的数据,1 < = N , M < = 10000000

    思路

    易证如果(n)(m)的倍数,那么([1,n])中和(m)互素的数的个数为$frac {n} {m}phi(m) (。那么)[1,N!](中和)M!(互素的个数就是)frac{N!}{M!}phi(M!)$。那么预处理出所有数的阶乘。再来考虑解决欧拉函数的处理。

    (phi(M!)=M!*frac{prod_{i=1}^{j}(p_i-1)}{prod _{i=1}^{j}p_i}),显然,(forall p_i,p_ileq m)。那我们前缀和(积)一波就可以了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define mod r
    #define ll long long
    #define maxn (int)(1e7+100)
    int t,r;
    ll factu[maxn];
    ll prodd[maxn],produ[maxn];
    ll ksm(ll num,ll times){
        ll ans = 1 , cur = num % mod;
        while( times ) {
            if( times & 1 ) ans *= cur , ans %= mod;
            cur *= cur , cur %= mod , times >>= 1;
        }
        return ans;
    }
    void init(){
        factu[1]=1;
        for(int i=2;i<maxn;i++){
            factu[i]=(ll)factu[i-1]*i;factu[i]%=mod;
        }
        static bool mark[maxn+1000]={0};
        produ[1]=1,prodd[1]=1;
        for(int i=2;i<maxn;i++){
            produ[i]=produ[i-1];prodd[i]=prodd[i-1];
            if(mark[i]){continue;}
            produ[i]*=(i-1);produ[i]%=mod;
            prodd[i]*=i;prodd[i]%=mod;
            for(int j=i;j<maxn;j+=i)mark[j]=1;
        }
        return;
    }
    void solve(){
        ll n,m;scanf("%lld%lld",&n,&m);
        if(n>=mod&&m<mod){puts("0");return;}
        ll ans=factu[n];ans%=mod;
        ans*=(produ[m]*ksm(prodd[m],mod-2)%mod)%mod;
        ans%=mod;
        printf("%lld
    ",ans);
    }
    int main(){
        //freopen("in","r",stdin);
        scanf("%d%d",&t,&r);
        init();
        while(t--)solve();
        return 0;
    }
    
  • 相关阅读:
    转《编程之美——微软技术面试心得》勘误表
    第一次 学习使用 智能指针
    test _todel
    (转 todo阅读)Android 官方博客 Android应用程序的内存分析(翻译)
    msdn snmp trap 研究可否 重入 转《Multiple Trap Registrations》
    wpbars在博客园开博客了
    创业失败的10个教训总结
    winform 的一种登录方法。
    快速建立Subversion
    (转)SQL Server 按某一字段分组取最大(小)值所在行的数据
  • 原文地址:https://www.cnblogs.com/GavinZheng/p/11041189.html
Copyright © 2011-2022 走看看