zoukankan      html  css  js  c++  java
  • 【刷题】洛谷 P3807 【模板】卢卡斯定理

    题目背景

    这是一道模板题。

    题目描述

    给定(n,m,p( 1le n,m,ple 10^5))

    (C_{n+m}^{m} mod p)

    保证 (p) 为prime

    (C) 表示组合数。

    一个测试点内包含多组数据。

    输入输出格式

    输入格式:

    第一行一个整数 (T( Tle 10 )),表示数据组数

    第二行开始共 (T) 行,每行三个数 (n,m,p),意义如上

    输出格式:

    共T行,每行一个整数表示答案。

    输入输出样例

    输入样例#1:

    2
    1 2 5
    2 1 5

    输出样例#1:

    3
    3

    题解

    卢卡斯定理的模板题

    [igg(egin{matrix} m \ n end{matrix}igg) mod p=igg(egin{matrix} m/p \ n/p end{matrix}igg)igg(egin{matrix} mmod p \ n~mod p end{matrix}igg) mod p ]

    具体应用就是预处理模数的fac和inv,然后两个组合数中后面那个肯定可以用预处理的算,前面那个如果 (n)(m) 还是比模数大,就一直递归下去。注意,当 (n) 小于 (m) 时,返回0
    证明看这里
    那这道题就裸啦

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXP=100000+10;
    ll fac[MAXP],inv[MAXP];
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    inline ll qexp(ll a,ll b,int n)
    {
    	ll res=1;
    	while(b)
    	{
    		if(b&1)res=res*a%n;
    		a=a*a%n;
    		b>>=1;
    	}
    	return res;
    }
    inline void init(int p)
    {
    	fac[0]=1;
    	for(register int i=1;i<p;++i)fac[i]=1ll*fac[i-1]*i%p;
    	inv[p-1]=qexp(fac[p-1],p-2,p);
    	for(register int i=p-2;i>=0;--i)inv[i]=1ll*inv[i+1]*(i+1)%p;
    }
    inline ll C(ll n,ll m,int p)
    {
    	if(n<m)return 0;
    	if(n<p&&m<p)return fac[n]*inv[m]%p*inv[n-m]%p;
    	else return C(n/p,m/p,p)*C(n%p,m%p,p)%p;
    }
    int main()
    {
    	int T;
    	read(T);
    	while(T--)
    	{
    		int n,m,p;
    		read(n);read(m);read(p);
    		init(p);
    		write(C(n+m,m,p),'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    uva 10127
    POJ 3280 Cheapest Palindrome
    看图学英语
    看图学英语
    算法 Tricks(四)—— 获取一个数二进制形式第一个不为 0 的位置
    算法 Tricks(四)—— 获取一个数二进制形式第一个不为 0 的位置
    Opencv Surf算子中keyPoints,描述子Mat矩阵,配对向量DMatch里都包含了哪些好玩的东东?
    强大的 function adapters
    强大的 function adapters
    transform、accumulate —— C++ 下的 MapReduce
  • 原文地址:https://www.cnblogs.com/hongyj/p/8974094.html
Copyright © 2011-2022 走看看