[luogu] P1869 愚蠢的组合数 卢卡斯定理

前言

因为上海站 被数学控死 所以最近会偏向于数学

传送门 :

思路

n < = 1 e 5 , k < = 1 e 5 n<=1e5 ,k<=1e5 n<=1e5,k<=1e5这么大的数怎么算呢 ? 直接暴力求解出来吗
(显然 算法基础课我的那个组合数还是没掌握

但是这题不需要求出值

只需要求出 是否是奇偶性就行,因此我们需要尽可能的将值变小

因此想到卢卡斯定理 :
( n m )   m o d   p = ( ⌊ n / p ⌋ ⌊ m / p ⌋ ) ⋅ ( n   m o d   p m   m o d   p )   m o d   p \left(\begin{array}{c}n \\ m\end{array}\right) \bmod p=\left(\begin{array}{l}\lfloor n / p\rfloor \\ \lfloor m / p\rfloor\end{array}\right) \cdot\left(\begin{array}{c}n \bmod p \\ m \bmod p\end{array}\right) \bmod p (nm)modp=(n/pm/p)(nmodpmmodp)modp

通过每次都 / 2 /2 /2 (log级别了)

我们既可以保证数的范围,又可以保证时间的复杂度

因此我们可以通过最常见的递归实现即可

CODE

int n,m;


int C(int n,int m)
{
	if(m == n)
	return 1;
	if(m == 0)
	return 0;
	if(n == 0)
	return 1;
	return C(n/2,m/2)*C(n%2,m%2);
}

void solve()
{
	cin>>m>>n;
	
	cout<<C(n,m)%2<<endl;
	
}
int main()
{
    int t;cin>>t;while(t -- )
    solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值