[欧拉函数]BZOJ 2186 沙拉公主的困惑

https://www.luogu.org/problem/P2155

分析

对一个阶乘求欧拉函数,可以想到欧拉函数的一个基本公式:

$\varphi (n)=n\prod_{i=1}^k \frac{p_i-1}{p_i}$

因为阶乘是乘积形式的,所以我将1~m中所有phi都搞出来,给他们的倍数累计贡献即可

然后逆元线性求掉,就随便搞搞了

 

#include <iostream>
#include <cstdio>
using namespace std;
const int N=1e7+1;
typedef long long ll;
int T,n,m;
int P,fac[N],inv[N],cal[N];
bool nonprime[N];
int prime[700010],cnt;

void Prime() {
    for (int i=2;i<N;i++) {
        if (!nonprime[i]) prime[++cnt]=i;
        for (int j=1;j<=cnt;j++) {
            if (1ll*i*prime[j]>=N) break;
            nonprime[i*prime[j]]=1;
            if (i%prime[j]==0)     break;
        }
    }
    inv[1]=1;fac[1]=1;cal[1]=1;
    for (int i=2;i<N;i++) {
        inv[i]=1ll*(P-P/i)*inv[P%i]%P,fac[i]=1ll*fac[i-1]*i%P;
        cal[i]=1ll*cal[i-1]*(nonprime[i]?1:1ll*(i-1)*inv[i]%P)%P;
    }
}

int main() {
    scanf("%d%d",&T,&P);
    Prime();
    while (T--) {
        scanf("%d%d",&n,&m);
        printf("%d\n",1ll*fac[n]*cal[m]%P);
    }
}
View Code

 

posted @ 2019-08-17 07:48  Vagari  阅读(161)  评论(0编辑  收藏  举报