QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#561226 | #8173. T Tile Placement Counting | rqoi031 | TL | 1ms | 4516kb | C++20 | 7.2kb | 2024-09-12 21:22:54 | 2024-09-12 21:22:54 |
Judging History
answer
#include<stdio.h>
#include<algorithm>
#include<numeric>
typedef unsigned int uint;
typedef unsigned long long ull;
constexpr uint mod{998244353};
constexpr uint plus(const uint &x,const uint &y) {
if(x+y>=mod) {
return x+y-mod;
}
return x+y;
}
constexpr uint minus(const uint &x,const uint &y) {
if(x<y) {
return x-y+mod;
}
return x-y;
}
constexpr uint power(uint x,uint y) {
uint s(1);
while(y>0) {
if(y&1) {
s=ull(s)*x%mod;
}
x=ull(x)*x%mod;
y>>=1;
}
return s;
}
constexpr bool check(const uint &n,const uint &s) {
int j(0);
for(uint i=0;i!=n;i++) {
if((j+=s>>i&1?1:-1)<0) {
return false;
}
}
return j==0;
}
uint id[1<<14|1];
constexpr uint maxn{429};
struct matrix {
uint n;
uint a[maxn][maxn];
constexpr matrix():n{},a{} {}
constexpr matrix(const uint &_n):n{_n},a{} {}
constexpr void clear() {
for(uint i=0;i!=n;i++) {
std::fill(a[i],a[i]+n,0u);
}
}
constexpr void resize(const uint &_n) {
n=_n,clear();
}
constexpr matrix mul(const matrix &x) const {
matrix z(x.n);
for(uint i=0;i!=z.n;i++) {
for(uint j=0;j!=z.n;j++) {
for(uint k=0;k!=z.n;k++) {
z.a[i][k]=(z.a[i][k]+ull(a[i][j])*x.a[j][k])%mod;
}
}
}
return z;
}
constexpr matrix &rmul(const matrix &x) {
const matrix y(*this);
clear();
for(uint i=0;i!=n;i++) {
for(uint j=0;j!=n;j++) {
for(uint k=0;k!=n;k++) {
a[i][k]=(a[i][k]+ull(y.a[i][j])*x.a[j][k])%mod;
}
}
}
return *this;
}
constexpr matrix &lmul(const matrix &x) {
const matrix y(*this);
clear();
for(uint i=0;i!=n;i++) {
for(uint j=0;j!=n;j++) {
for(uint k=0;k!=n;k++) {
a[i][k]=(a[i][k]+ull(x.a[i][j])*y.a[j][k])%mod;
}
}
}
return *this;
}
constexpr matrix &square() {
const matrix y(*this);
clear();
for(uint i=0;i!=n;i++) {
for(uint j=0;j!=n;j++) {
for(uint k=0;k!=n;k++) {
a[i][k]=(a[i][k]+ull(y.a[i][j])*y.a[j][k])%mod;
}
}
}
return *this;
}
};
struct vector {
uint n;
uint a[maxn];
constexpr vector():n{},a{} {}
constexpr vector(const uint &_n):n{_n},a{} {}
constexpr void clear() {
std::fill(a,a+n,0u);
}
constexpr void resize(const uint &_n) {
n=_n,clear();
}
constexpr vector &lmul(const matrix &x) {
const vector y(*this);
clear();
for(uint i=0;i!=n;i++) {
for(uint j=0;j!=n;j++) {
a[i]=(a[i]+ull(x.a[i][j])*y.a[j])%mod;
}
}
return *this;
}
};
namespace dsu {
uint fa[60];
inline void init(const uint &n) {
std::iota(fa,fa+n,0);
}
uint getf(const uint &x) {
return fa[x]==x?x:fa[x]=getf(fa[x]);
}
inline void merge(const uint &x,const uint &y) {
fa[getf(y)]=getf(x);
}
}
uint stk[30],tag[30];
int main() {
uint n;ull m;
scanf("%u%llu",&n,&m);
if((n&3)||(m&3)) {
return puts("0"),0;
}
n>>=1,m>>=1;
std::fill(id,id+(1<<n),-1u);
uint tot(0);
for(uint i=0;i!=1<<n;i++) {
if(check(n,i)) {
id[i]=tot++;
}
}
matrix A(tot);
for(uint i=0;i!=1<<n;i++) {
if(id[i]==-1) {
continue;
}
for(uint j=0;j!=1<<(n>>1)-1;j++) {
dsu::init(n<<1);
uint top(0);
for(uint k=0;k!=n;k++) {
if(i>>k&1) {
stk[top++]=k;
}
else {
dsu::merge(k,stk[--top]);
}
}
dsu::merge(0,n);
dsu::merge(n-1,(n<<1)-1);
for(uint k=0;k!=(n>>1)-1;k++) {
if(j>>k&1) {
dsu::merge(k<<1|1,(k<<1|1)+n);
dsu::merge(k+1<<1,(k+1<<1)+n);
}
else {
dsu::merge(k<<1|1,k+1<<1);
dsu::merge((k<<1|1)+n,(k+1<<1)+n);
}
}
uint _i(0);
std::fill(tag,tag+(n<<1),0);
for(uint k=0;k!=n;k++) {
if(!tag[dsu::getf(n+k)]) {
tag[dsu::getf(n+k)]=1,_i|=1<<k;
}
}
uint c(0);
for(uint k=0;k!=n;k++) {
if(!tag[dsu::getf(k)]) {
tag[dsu::getf(k)]=1,++c;
}
}
A.a[id[_i]][id[i]]+=1u<<c;
}
}
matrix B(tot);
for(uint i=0;i!=1<<n;i++) {
if(id[i]==-1) {
continue;
}
for(uint j=0;j!=1<<(n>>1);j++) {
dsu::init(n<<1);
uint top(0);
for(uint k=0;k!=n;k++) {
if(i>>k&1) {
stk[top++]=k;
}
else {
dsu::merge(k,stk[--top]);
}
}
for(uint k=0;k!=n>>1;k++) {
if(j>>k&1) {
dsu::merge(k<<1,(k<<1)+n);
dsu::merge(k<<1|1,(k<<1|1)+n);
}
else {
dsu::merge(k<<1,k<<1|1);
dsu::merge((k<<1)+n,(k<<1|1)+n);
}
}
uint _i(0);
std::fill(tag,tag+(n<<1),0);
for(uint k=0;k!=n;k++) {
if(!tag[dsu::getf(n+k)]) {
tag[dsu::getf(n+k)]=1,_i|=1<<k;
}
}
uint c(0);
for(uint k=0;k!=n;k++) {
if(!tag[dsu::getf(k)]) {
tag[dsu::getf(k)]=1,++c;
}
}
B.a[id[_i]][id[i]]+=1u<<c;
}
}
matrix C(B.mul(A));
vector S(tot);
S.a[([&]()->uint {
uint res(0);
for(uint i=0;i!=n;i+=2) {
res|=1u<<i;
}
return id[res];
}())]=1;
for(ull i=(m>>1)-1;i!=0;i>>=1) {
if(i&1) {
S.lmul(C);
}
C.square();
}
S.lmul(A);
uint ans(0);
for(uint i=0;i!=1<<n;i++) {
if(id[i]==-1) {
continue;
}
dsu::init(n);
uint top(0);
for(uint j=0;j!=n;j++) {
if(i>>j&1) {
stk[top++]=j;
}
else {
dsu::merge(j,stk[--top]);
}
}
for(uint j=0;j!=n>>1;j++) {
dsu::merge(j<<1,j<<1|1);
}
std::fill(tag,tag+n,0);
uint c(0);
for(uint j=0;j!=n;j++) {
if(!tag[dsu::getf(j)]) {
tag[dsu::getf(j)]=1,++c;
}
}
ans=(ans+(ull(S.a[id[i]])<<c))%mod;
}
printf("%u\n",ans);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 4516kb
input:
4 4
output:
2
result:
ok "2"
Test #2:
score: 0
Accepted
time: 1ms
memory: 4236kb
input:
2 8
output:
0
result:
ok "0"
Test #3:
score: 0
Accepted
time: 1ms
memory: 4496kb
input:
12 3456
output:
491051233
result:
ok "491051233"
Test #4:
score: 0
Accepted
time: 0ms
memory: 4308kb
input:
1 1
output:
0
result:
ok "0"
Test #5:
score: 0
Accepted
time: 1ms
memory: 4332kb
input:
20 999999999999999983
output:
0
result:
ok "0"
Test #6:
score: 0
Accepted
time: 1ms
memory: 4296kb
input:
24 999999999999999994
output:
0
result:
ok "0"
Test #7:
score: 0
Accepted
time: 1ms
memory: 4336kb
input:
24 999999999999999955
output:
0
result:
ok "0"
Test #8:
score: -100
Time Limit Exceeded
input:
28 999999999999999928