題目描述:
給出 個互不相同的數 ,求一個長爲 的序列 ,滿足 的方案數模2的值。
題目分析:
設每個 出現了 次,那麼 ,考慮對應到排列上,那麼序列 對方案數的貢獻次數是
那麼一個序列 的貢獻模2餘1,則要求上面的式子不能被2整除,我們知道式子中含2的因子數
而 ,與庫默爾定理類似,這意味着在二進制下做加法不能進位。即 是 二進制下的子集
那麼考慮 每一位 1 分配給哪個 ,即求
的序列 的方案數模 2
從低位往高位類數位DP,每次可以確定最低位,設狀態 爲已經確定了前 位,當前的和爲 的方案數,那麼轉移就是加入一個 。然後根據 在當前位的值確定保留哪些方案,然後整體除以2。和最大爲
複雜度 ,bitset優化至
Code:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int T,K,A[205],Mx;
LL N,S;
bitset<200005>f,g;
int main()
{
for(scanf("%d",&T);T--;){
scanf("%lld%lld%d",&N,&S,&K),Mx=0;
for(int i=1;i<=K;i++) scanf("%d",&A[i]),Mx=max(Mx,A[i]);
f.reset(),f[0]=1;
for(int i=0;N;N>>=1,S>>=1,i++){
if(N&1){
g.reset();
for(int j=1;j<=K;j++) g^=f<<A[j];
}
else g=f;
f.reset();
for(int j=S&1;j<=2*Mx;j+=2) f[j>>1]=g[j];
}
printf("%d\n",int(f[S]));
}
}