Gym - 102470C Lights

    科技2022-07-12  131

    Statement:

          G i v e n   v ∈ { 0 , 1 } n , h o w   m a n y   s e t s   o f   m   d i s t i n c t   v e c t o r s   i n   { 0 , 1 } n   s u c h   t h a t   v 1 ⊕ v 2 ⊕ . . . ⊕ v m = v    ( a d d i t i o n    i s    b i t w i s e     X O R ) . Given \ v \in \{0, 1\}^n , how \ many \ sets \ of \ m \ distinct \ vectors \ in \ \{0, 1\} ^n \ such \ that \ v_1 ⊕ v_2 ⊕ . . . ⊕ v_m = v \ \ (addition \ \ is \ \ bitwise \ \ \ XOR). Given v{0,1}n,how many sets of m distinct vectors in {0,1}n such that v1v2...vm=v  (addition  is  bitwise   XOR).

    Solution:

          我们任意选择 m − 1 m-1 m1 个向量 v 1 , v 2 , . . . . v m − 1 v_1,v_2,....v_{m-1} v1,v2,....vm1,一定存在一个向量 v m v_m vm让其异或和为 v v v.但考虑到可能 v m v_m vm和前 m − 1 m-1 m1个向量的某个向量相同,我们考虑去除这一部分.       因为 v m v_m vm与某个向量相同,即 v m ⊕ v i = 0 v_m \oplus v_i = 0 vmvi=0,我们不妨把这两个向量提出来,剩下的 m − 2 m-2 m2个向量的异或和依旧为 v v v,即选择 m − 2 m-2 m2个向量的方案数.可以通过这种方式递推,最后求解.

          此外,我们发现 ( m b i t n ) 中 b i t n 很 大 . { m \choose bit_n} 中bit_n很大. \\ (bitnm)bitn. 利用卢卡斯定理 ( m b i t n ) m o d   p = ( m   m o d   p b i t n   m o d   p ) ⋅ ( ⌊ m p ⌋ ⌊ b i t n p ⌋ ) {m \choose bit_n} mod \ p = {m \ mod \ p \choose bit_n \ mod \ p} \cdot {\lfloor \frac m p\rfloor \choose \lfloor \frac {bit_{n}} {p}\rfloor} (bitnm)mod p=(bitn mod pm mod p)(pbitnpm)

    其中 ⌊ m p ⌋ \lfloor \frac m p\rfloor pm为0,所以该部分为 1,结果等于前部分

    Code:

    #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <stack> #include <bitset> #include <vector> #include <map> #include <string> #include <cstring> #define fir first #define sec second using namespace std; typedef long long ll; const ll mod = 10567201; const int maxn = mod; ll bit[maxn],fac[maxn]; ll fast(ll a,ll b) { ll sum = 1; while(b) { if(b&1) sum = sum*a%mod; a = a*a %mod; b >>= 1; } return sum; } ll inv(int x) {return fast(x,mod-2);} ll C(int x,int y) { if(y > x) return 0; return fac[x] * inv(fac[y])%mod * inv(fac[x-y])%mod; } int n,m,v; ll solve(int n,int m,int v) { if(m == 0 || m == 1) { if(m == 1) return 1; if(m == 0) return v? 0:1; } ll res = C(bit[n],m-1); return (res %mod- (bit[n] - m+2 + mod) %mod * solve(n,m-2,v)%mod+mod)*inv(m)%mod; } int main() { bit[0] = fac[0] = 1; for(int i=1;i<=mod;i++) { bit[i] = (bit[i-1]<<1)%mod; fac[i] = (fac[i-1]*i)%mod; } while(scanf("%d%d%d",&n,&m,&v) && n && m ) { printf("%lld\n", solve(n,m,v)); } return 0; }
    Processed: 0.016, SQL: 8