出来の悪かった回。
https://atcoder.jp/contests/arc146/tasks/arc146_c
問題
整数Nが与えられる。
0以上2^N未満の整数の集合Sのうち、以下を満たすのは何通りか。
- Sの空でない部分集合Tは、要素数が奇数がXORを取ると非0かのいずれかを満たす。
解法
dp(k) := 条件を満たすk要素のS
とする。dp(0)=1、dp(1)=2^Nである。
以後、dp(k)からdp(k+1)を求めて行く。
k要素のSに新たな要素を加えることを考える。
Sの部分集合のうち奇数要素のxorとなるものは足せない。逆にそうでないものは足せるので、dp(k+1)=dp(k)*(2^N-2^(k-1))となる。
int N; const ll mo=998244353; ll dp[202020]; ll modpow(ll a, ll n = mo-2) { ll r=1;a%=mo; while(n) r=r*((n%2)?a:1)%mo,a=a*a%mo,n>>=1; return r; } void solve() { int i,j,k,l,r,x,y; string s; cin>>N; dp[0]=1; dp[1]=modpow(2,N); ll ret=dp[0]+dp[1]; for(i=2;i<=N+1;i++) { dp[i]=dp[i-1]*(mo+modpow(2,N)-modpow(2,i-2))%mo*modpow(i)%mo; ret+=dp[i]; } cout<<ret%mo<<endl; }
まとめ
これはすんなり解いておきたかったな…。