BZOJ 3823 定情信物【脑推公式/找规律,线性求逆元,坑爹的数论题细节x

本文介绍了一种使用组合数学原理求解特定问题的方法,并通过C++代码实现了高效的计算。文章详细解释了如何利用逆元来处理组合数计算中的模运算问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果用f[i][j]表示i维空间里的j维元素有多少个,有公式 f[i][j] = C(i,j) * 2^(i-j)

……看题解似乎都是找规律的啊……sro mhy orz

考虑j维向量的方向有C(i,j)个,对于每个方向的向量,可以放置的位置的数量 显然就是剩下的几维随便填的方案数,2^(i-j)

毛神他们加的数据……大概就是当n>p的时候……p的倍数没有逆元这样的毒瘤数据,稍微记一下有多少个p就好了

……

哦还有线性地求1~n的逆元……私觉得Miskcoo大爷讲得很稳

传送门:http://blog.miskcoo.com/2014/09/linear-find-all-invert


代码:

#include<bits/stdc++.h>
#define MAXN 10000007 
using namespace std;	int n,p;
int inv[MAXN];
int cf2[MAXN];
int rec_fac = 1,rec_fac_p;

inline void init(){
	inv[1] = 1 ;
	for(register int i=2;i<=min(n,p-1);++i)	inv[i] = 1ll * (p - p/i) * inv[p%i] % p;
	cf2[0] = 1 ;
	for(register int i=1;i<=n;++i)	cf2[i] = cf2[i-1] * 2 % p;
}
int ans = 0;


inline void work(){
	int now = 1;
	ans = cf2[n] ^ 1;
	for(register int i = 1; i<n;++i,now = now*2 % p){
		int k = n - i + 1;
		while(!(k%p))	++rec_fac_p,k/=p;
		rec_fac = 1ll * rec_fac * k % p;
		k = i ;
		while(!(k%p))	--rec_fac_p,k/=p;
		rec_fac = 1ll * rec_fac * inv[k%p] % p;
		if(!rec_fac_p)
			ans ^= (int)(1ll * rec_fac * cf2[n-i] % p);
//		printf("%d\n",ans);
	}
	printf("%d",ans);
}

int main(){
	scanf("%d%d",&n,&p);
	init();
	work();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值