杨辉三角,组合数,卢卡斯定理

题面:https://codeforces.com/problemset/problem/2072/F
求某个数的组合数次幂的异或
由于异或性质,只跟组合数的奇偶有关。

前置知识

杨辉三角形的第i行第j个元素为\(C_i^j\)

卢卡斯定理 (Lucas' Theorem)

对于素数 \(p\) 和非负整数 \(n\)\(k\),组合数模 \(p\) 满足:

\[\binom{n}{k} \equiv \prod_{i=0}^{m} \binom{n_i}{k_i} \pmod{p} \]

其中 \(n_i\)\(k_i\)\(n\)\(k\)\(p\)-进制展开系数:

\[\begin{aligned} n &= n_m p^m + n_{m-1} p^{m-1} + \cdots + n_0 \\ k &= k_m p^m + k_{m-1} p^{m-1} + \cdots + k_0 \end{aligned} \]

特例:模 2(奇偶性判定)

\(p=2\) 时:

\[\binom{n}{k} \text{ 是奇数 } \iff \forall i,\ k_i \leq n_i \iff (k \ \& \ n) = k \]

用位运算表示为:
(k & n) == k

说人话就是,对这题来说,在模2意义下,组合数可以转化为n,m在二进制位下对应的数的组合数的乘积,由于要保证为奇数,所以模2为1不为0,所以不能存在\(C_0^1 = 0\)

#include<bits/stdc++.h>
using namespace std;
int com(int n,int r){
    if(n-r>r)r=n-r;
    int i,j,s=1;
    for(i=0,j=1;i<r;i++){
        s*=(n-i);
        for(;j<=r&&s%j==0;j++)s/=j;
    }
    return s;
}
int qmi(int base,int mi){
    int result = 0;
    while(mi){
        if(mi&1){
            result^=base;
        }
        base^=base;
        mi>>=1;
    }
    return result;
}
void solve(){
    int n,k;
    cin>>n>>k;
    //for(int i=0;i<n;i++)cout<<qmi(k,com(n-1,i))<<" ";
    for(int i=0;i<n;i++){
        if(((n-1)&i)==i)cout<<k<<" ";
        else cout<<0<<" ";
    }
    cout<<endl;
}
int main(){
    int t;
    cin>>t;
    while(t--)solve();
}```
posted @ 2025-07-19 14:48  majikko  阅读(63)  评论(0)    收藏  举报