首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/884/E
来源:牛客网
涉及:位运算,容斥定义,dp
点击这里回到2019牛客暑期多校训练营解题—目录贴
题目如下:
代码如下
#include <iostream>
using namespace std;
typedef long long ll;
const int mx = 60;
const ll mod = 998244353;
ll C[64][64], S[64][64];
ll n, a;
int t;
ll qpow(ll a, ll b){
ll sum = 1;
while(b){
if(b & 1ll) sum = sum * a % mod;
a = a * a % mod;
b >>= 1;
}
return sum;
}
void init(){
C[0][0] = 1;
for(int i = 1; i <= mx; i++){
C[i][0] = 1;
for(int j = 1; j <= i; j++){
C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod;
}
}
for(int i = 0; i <= mx; i++){
for(int j = 0; j <= mx; j++){
for(int p = 0; p <= i; p++){
for(int q = 0; q <= j; q++){
if((p+2*q) % 3 == 0){
S[i][j] += C[i][p] * C[j][q] % mod;
S[i][j] %= mod;
}
}
}
}
}
return;
}
int main(){
init();
cin >> t;
while(t--){
int odd = 0, even = 0;
ll ans = 0;
scanf("%lld%lld", &n, &a);
for(int i = 0; i < 63; i++){
if(a & (1ll << i)){
if(i % 2 == 0) even++;
else odd++;
}
}
for(int i = 0; i <= odd; i++){
for(int j = 0; j <= even; j++){
ll temp = C[odd][i] * C[even][j] % mod * qpow(S[i][j], n) % mod;
if((odd+even-i-j) % 2 != 0) temp *= -1;
ans += temp;
ans %= mod;
}
}
ans = (ans + mod) % mod;
printf("%lld\n", ans);
}
return 0;
}