专栏文章

题解:CF2072F Goodbye, Banker Life

CF2072F题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio1o85x
此快照首次捕获于
2025/12/02 11:54
3 个月前
此快照最后确认于
2025/12/02 11:54
3 个月前
查看原文

转化为奇偶判定 + Lucas 定理

首先不难发现 fi,jf_{i,j} 的取值只可能是 00kk,不妨把 kk 看作 11。那么通过 fi,jf_{i,j} 的奇偶性即可确定 fi,jf_{i,j} 的值。
由于异或的本质为二进制下的不进位加法,故可以把 fi,j=fi1,j1fi1,jf_{i,j}=f_{i-1,j-1} \oplus f_{i-1,j} 转换为 fi,j=fi1,j1+fi1,jf_{i,j}=f_{i-1,j-1} + f_{i-1,j},并把问题转换为判断 fi,jf_{i,j} 的奇偶性。
注意到转换后的 fi,jf_{i,j} 是杨辉三角。
对于杨辉三角:
  • 当行号和列号均从 0 开始计数:第 ii 行第 jj 列的取值为 (ij)\binom{i}{j}
  • 当行号和列号均从 1 开始计数:第 ii 行第 jj 列的取值为 (i1j1)\binom{i-1}{j-1}
由于行号和列号规定均从 11 开始计数,因此对于 fi,jf_{i,j},它的值就是 (i1j1)\binom{i-1}{j-1} 的值。
那么显然可以用 Lucas 定理秒了。回顾 Lucas 定理:
(ij)(ipjp)×(imodpjmodp)(modp)\binom{i}{j} \equiv \binom{\lfloor \frac{i}{p} \rfloor}{\lfloor \frac{j}{p} \rfloor} \times \binom{i \bmod p }{j \bmod p } \pmod p
那么最终输出第 nn 行的第 jj 个数时,即输出 lucas(n1,j)×k\operatorname{lucas}(n-1,j) \times k
CPP
int n,k;
int fastpow(int a,int n,int mod){
	int res=1;
	while(n){
		if(n&1) res=res*a%mod;
		a=a*a%mod;
		n>>=1;
	}
	return res;
}
int getC(int n,int m,int mod){
	int res=1;
	for(int i=n,j=1;j<=m;i--,j++){
		res=res*i%mod;
		res=res*fastpow(j,mod-2,mod)%mod;
	}
	return res;
}
int lucas(int n,int m,int p){
	if(!m) return 1;
	return lucas(n/p,m/p,p)*getC(n%p,m%p,p);
}
void solve(){
	cin>>n>>k;
	rep(i,1,n) cout<<lucas(n-1,i-1,2)*k<<" ";
}
此外还有一个结论做法:
mod=2\bmod=2 时有一个结论,(nm)\binom{n}{m} 等价于 n&m==mn \& m ==m
也就是说代码还可以这样写:
CPP
int n,k;
int calc(int n,int m){
	return (n&m)==m;
}
void solve(){
	cin>>n>>k;
	rep(i,1,n) cout<<calc(n-1,i-1)*k<<" ";
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...