SDOI 2008沙拉公主的困惑

星期四, 23. 二月 2017 05:10下午

SDOI 2008沙拉公主的困惑
题目大意
求1-N!中与M!互质的数的个数;
思路

参考神犇の博客

N>M
N! M!
所以我们可以将N!分为 N!M! 段,那么这样的话,每段长度为M!
p与q互质
p+k仍然与q互质
那么 根据这个性质,就可以得到等式
sum= N!M! φ(M!)
  = N!M! M!(111p1) (111p2) (111p3) (111pk)
  =N! (111p1) (111p2) (111p3) (111pk)

先预处理出N!和 φ (M!)可以做到蜜汁O(1)出解;

#include <cstdio>
#include <algorithm>
#include <cmath>
#define max(a,b) a>b?a:b
using namespace std;


typedef long long LL;
const int MAXN = 10000000+50;
const int N = 10000+50;
int fac[MAXN],sum[MAXN],inv[MAXN],num;
int t,mod,A[N],B[N],maxn;
int prime1[MAXN];
bool prime[MAXN];

void Read(int &);

void init(int Maxn)
{
    Maxn++;
    sum[1]=1,fac[1]=1,inv[1]=1;
    for(int i=2;i<Maxn;i++){
        if(!prime[i])
            prime1[++num]=i;
        for(int j=1;j<=num && i*prime1[j]<Maxn;j++){
               prime[i*prime1[j]]=1;
            if(i%prime1[j]==0) break;
        }
    }    //线性筛函数
    for(int i=2;i<=Maxn;i++)
    {
        sum[i]=((LL)sum[i-1]*i%mod)%mod; //预处理阶乘
        if(i<mod)    inv[i]=(LL)(mod-mod/i)%mod*inv[mod%i]%mod;//预处理逆元
        if(!prime[i])    fac[i]=(LL)fac[i-1]*(i-1)%mod*inv[i%mod]%mod;
        else fac[i]=fac[i-1];
    } //改成三个循环TLE3个点;
}

int main()
{
    Read(t),Read(mod);
    for(int i=1;i<=t;i++)
        Read(A[i]),Read(B[i]),maxn=max(maxn,A[i]);
    init(maxn);
    for(int i=1;i<=t;i++)
        printf("%lld\n",(LL)fac[B[i]]*sum[A[i]]%mod);
    return 0;
}

void Read(int &in){
    static char ch;
    for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) ;
    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值