BZOJ 2186 沙拉公主的困惑

Posted on 2016-10-11 15:34  ziliuziliu  阅读(161)  评论(0编辑  收藏  举报

线性筛。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 10000050
using namespace std;
int t,mod,n,m,fac[maxn],prime[maxn],top=0,f1[maxn],f2[maxn],x,inv[maxn];
bool vis[maxn];
void get_table()
{
    fac[1]=1;for (int i=2;i<=maxn;i++) fac[i]=(long long)fac[i-1]*i%mod;
    inv[1]=1;
    for (int i=2;i<=maxn;i++)
    {
        inv[i]=(-(long long)mod/i*inv[mod%i]%mod+mod)%mod;
        if (!vis[i]) prime[++top]=i;
        for (int j=1;j<=top && i*prime[j]<=maxn;j++)
        {
            vis[i*prime[j]]=true;
            if (!(i%prime[j])) break;
        }
    }
    f1[0]=f2[0]=1;
    for (int i=1;i<=top;i++)
    {
        f1[i]=((long long)f1[i-1]*(prime[i]-1))%mod;
        f2[i]=((long long)f2[i-1]*inv[prime[i]])%mod;
    }
}
int find(int x)
{
    int l=1,r=top,ans=0;
    while (l<=r)
    {
        int mid=l+r>>1;
        if (prime[mid]<=x) {ans=mid;l=mid+1;}
        else r=mid-1;
    }
    return ans;
}
int main()
{
    scanf("%d%d",&t,&mod);
    get_table();
    for (int i=1;i<=t;i++)
    {
        scanf("%d%d",&n,&m);
        x=find(m);
        long long ans=(((long long)fac[n]*(long long)f1[x])%mod*(long long)f2[x])%mod;
        printf("%lld\n",ans);
    }
    return 0;
}