細々とした知識が要る問題。
https://yukicoder.me/problems/no/1531
問題
非負整数N,Kが与えられる。
無限のサイズのグリッドに対し、初期状態でほとんどの要素はA(0,i,j)=0とする。
例外的に、y and K = yとなるyに対しA(0,0,y)=1とする。
いずれかの添え字が負である要素は、値が常に0であるものとする。
A(n,i,j)=A(n-1,i,j) xor A(n-1,i-1,j) xor A(n-1,i,j-1)
とするとき、A(N,*,*)が1となる要素の数を答えよ。
解法
K=0の時を考える。
A(N,x,y)は、(0,0)から初めて、右への移動をx回、下への移動をy回、その場にとどまることを(N-x-y)回行う移動経路の組み合わせを考えるとA(N,x,y)=Comb(N,x)*Comb(N-x,y) mod 2といえる。
Comb(a,b)が奇数である条件はa and b = bなので、求めるべきはである。
これを変形するとである。
Kが任意の場合を考える。
A(0,0,y)=1となる条件より、Comb(K,y)が奇数となるyでA(0,0,y)=1となる。
これは、移動しない・または下に移動することをK回余分に行うことと等しい。
よってを求めればよい。
popcount(x+K)がある値になるxの数え上げは、Nの下のビットから順に、xに含める・含めないを考えて列挙していくとよい。
ll N,K; ll dp[62][65][2]; const ll mo=998244353; void solve() { int i,j,k,l,r,x,y; string s; cin>>N>>K; dp[0][0][0]=1; FOR(i,61) { int n=(N>>i)%2; int k=(K>>i)%2; FOR(j,62) { FOR(x,2) { // not take (dp[i+1][j+(k^x)][k&x]+=dp[i][j][x])%=mo; if(n) { (dp[i+1][j+(k^x^1)][((k+x+1)>>1)]+=dp[i][j][x])%=mo; } } } } ll ret=0; FOR(j,62) (ret+=dp[61][j][0]%mo*((1LL<<j)%mo))%=mo; cout<<ret<<endl; }
まとめ
andの条件からLucasの定理につなげていくのか。