QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#204035 | #874. Long Grid Covering | woshiluo | AC ✓ | 660ms | 4204kb | C++20 | 6.0kb | 2023-10-07 00:18:57 | 2023-10-07 00:18:57 |
Judging History
answer
/*
* b.cpp 2023-09-30
* Copyright (C) 2023 Woshiluo Luo <[email protected]>
*
* 「Two roads diverged in a wood,and I—
* I took the one less traveled by,
* And that has made all the difference.」
*
* Distributed under terms of the GNU GNU AGPLv3+ license.
*/
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <map>
#include <array>
#include <queue>
#include <vector>
#include <random>
#include <algorithm>
typedef const int cint;
typedef long long ll;
typedef unsigned long long ull;
inline bool isdigit( const char cur ) { return cur >= '0' && cur <= '9'; }/*{{{*/
template <class T>
T Max( T a, T b ) { return a > b? a: b; }
template <class T>
T Min( T a, T b ) { return a < b? a: b; }
template <class T>
void chk_Max( T &a, T b ) { if( b > a ) a = b; }
template <class T>
void chk_Min( T &a, T b ) { if( b < a ) a = b; }
template <typename T>
T read() {
T sum = 0, fl = 1;
char ch = getchar();
for (; isdigit(ch) == 0; ch = getchar())
if (ch == '-') fl = -1;
for (; isdigit(ch); ch = getchar()) sum = sum * 10 + ch - '0';
return sum * fl;
}
template <class T>
T pow( T a, ll p ) {
T res = 1;
while( p ) {
if( p & 1 )
res = res * a;
a = a * a;
p >>= 1;
}
return res;
}/*}}}*/
const int mod = 1e9 + 7;
struct ModInt {/*{{{*/
int32_t cur;
ModInt( const int64_t _cur = 0 ) { cur = ( ( ( _cur % mod ) + mod ) % mod ); }
inline ModInt operator+ ( const ModInt &b ) const { return ( cur + b.cur ) % mod; }
inline ModInt operator- ( const ModInt &b ) const { return ( ( ( cur - b.cur ) % mod ) + mod ) % mod; }
inline ModInt operator* ( const ModInt &b ) const { return ( 1LL * cur * b.cur ) % mod; }
inline ModInt operator/ ( const ModInt &b ) const { return ( 1LL * cur * pow( b, mod - 2 ).cur ) % mod; }
inline void operator+= ( const ModInt &b ) { (*this) = (*this) + b; }
inline void operator-= ( const ModInt &b ) { (*this) = (*this) - b; }
inline void operator*= ( const ModInt &b ) { (*this) = (*this) * b; }
inline void operator/= ( const ModInt &b ) { (*this) = (*this) / b; }
inline void output( const char end = '\n' ) { printf( "%d%c", cur, end ); }
};/*}}}*/
const int32_t P = 1 << 9;
int32_t hash( const int32_t x, const int32_t y ) {
return ( 2 - y ) * 3 + x;
}
uint32_t full_pow( const uint32_t cur ) {
return 1 << cur;
}
uint32_t set_bit( const uint32_t cur, const uint32_t pos ) {
return cur | full_pow(pos);
}
bool chk_pos( const uint32_t cur, const uint32_t pos ) {
return ( cur >> pos ) & 1;
}
ModInt f[P], orip[P][P];
const int LP = 24;
struct Matrix {/*{{{*/
ModInt a[LP][LP];
Matrix( const int cur = 0 ) {
if( cur )
for( int i = 0; i < LP; i ++ )
a[i][i] = 1;
}
Matrix operator* ( const Matrix &_b ) const {
Matrix res;
for( int i = 0; i < LP; i ++ ) {
for( int j = 0; j < LP; j ++ ) {
for( int k = 0; k < LP; k ++ ) {
res.a[i][j] += a[i][k] * _b.a[k][j];
}
}
}
return res;
}
void operator*= ( const Matrix &_b ) { (*this) = (*this) * _b; }
} p;/*}}}*/
struct Node { int32_t x, y; };
Node block[][3] = {
{ { 0, 0 }, { 0, 1 }, { 0, 2 } },
{ { 0, 0 }, { 1, 0 }, { 2, 0 } },
{ { 0, 0 }, { 0, 1 }, { 1, 0 } },
{ { 0, 0 }, { 0, 1 }, { 1, 1 } },
{ { 0, 0 }, { 1, 0 }, { 1, 1 } },
{ { 0, 1 }, { 1, 0 }, { 1, 1 } },
};
int main() {
#ifdef woshiluo
freopen( "l.in", "r", stdin );
freopen( "l.out", "w", stdout );
#endif
std::vector<uint32_t> blocks;
{/*{{{*/
auto chk = [] ( const int32_t cur, const int32_t left, const int32_t rig ) { return ( cur >= left ) && ( cur < rig ); };
for( int o = 0; o < 6; o ++ ) {
const auto v = block[o];
for( int i = 0; i < 3; i ++ ) {
int mask = 0;
bool flag = true;
for( int k = 0; k < 3; k ++ ) {
const auto node = v[k];
if( chk( node.x + i, 0, 3 ) ) {
mask = set_bit( mask, hash( node.x + i, node.y ) );
continue;
}
flag = false;
break;
}
if( !flag )
continue;
blocks.push_back(mask);
}
}
}/*}}}*/
for( uint32_t sta = 0; sta < full_pow(12); sta ++ ) {/*{{{*/
bool flag = true;
int mask = 0;
for( int j = 0; j < 12; j ++ ) {
if( chk_pos( sta, j ) == false )
continue;
if( mask & blocks[j] )
flag = false;
mask |= blocks[j];
}
if( flag )
f[mask] += 1;
}
/*}}}*/
for( uint32_t i = 0; i < full_pow(6); i ++ ) {
for( uint32_t j = 0; j < full_pow(6); j ++ ) {
if( ( ( j >> 3 ) & 7 ) < ( i & 7 ) )
continue;
const int32_t mask = ( ( 7 ^ ( ( i >> 3 ) & 7 ) ) << 6 ) |
( ( ( ( j >> 3 ) & 7 ) ^ ( i & 7 ) ) << 3 ) |
( ( j & 7 ) );
orip[i][j] += f[mask];
}
}
std::vector<int> nums;
for( uint32_t i = 0; i < full_pow(6); i ++ ) {
for( uint32_t j = 0; j < full_pow(6); j ++ ) {
if( orip[i][j].cur ) {
if( i != 0 && j != 0 && ( i <= 7 || std::__popcount(i) < 3 || std::__popcount(j) < 3 ) ) {
orip[i][j] = 0;
}
else {
nums.push_back( i );
nums.push_back( j );
#ifdef woshiluo
printf( "(%d,%d) = %3d\n", i, j, orip[i][j].cur );
#endif
}
}
}
}
std::sort( nums.begin(), nums.end() );
nums.erase( std::unique( nums.begin(), nums.end() ), nums.end() );
auto find = [&nums]( const int32_t cur ) { return std::lower_bound( nums.begin(), nums.end(), cur ) - nums.begin(); };
for( uint32_t i = 0; i < full_pow(6); i ++ ) {
for( uint32_t j = 0; j < full_pow(6); j ++ ) {
if( orip[i][j].cur ) {
p.a[ find(i) ][ find(j) ] = orip[i][j];
}
}
}
int T = read<int>();
std::vector<std::pair<ll, int>> q;
std::vector<ModInt> ans(T);
for( int i = 0; i < T; i ++ ) {
q.push_back( { read<ll>(), i } );
}
std::sort( q.begin(), q.end() );
Matrix a;
a.a[0][0] = 1;
ll la = 0;
for( auto &pair: q ) {
const auto diff = pair.first - la;
la = pair.first;
if( diff != 0 )
a = a * pow( p, diff );
ans[ pair.second ] = a.a[0][0];
}
for( auto &x: ans )
x.output();
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 4204kb
input:
4 1 2 3 10
output:
1 3 10 8266
result:
ok 4 number(s): "1 3 10 8266"
Test #2:
score: 0
Accepted
time: 48ms
memory: 4056kb
input:
100 591 417 888 251 792 847 685 3 182 461 102 348 555 956 771 901 712 878 580 631 342 333 285 899 525 725 537 718 929 653 84 788 104 355 624 803 253 853 201 995 536 184 65 205 540 652 549 777 248 405 677 950 431 580 600 846 328 429 134 983 526 103 500 963 400 23 276 704 570 757 410 658 507 620 984 2...
output:
398162564 3923746 347206084 937652677 511984221 356815867 634269583 10 492672877 107350060 647965529 633393631 911425824 746373395 426043114 551287175 772111460 994877654 877599230 88346652 250024200 154039310 461178023 487763582 763918729 537233428 570954868 210301204 911464697 237056565 669291182 ...
result:
ok 100 numbers
Test #3:
score: 0
Accepted
time: 660ms
memory: 3980kb
input:
100 955967370573984956 113166936398978672 934415284373637608 774686535590919223 668528836699949629 65629257521619533 811940940990692618 915621972787306932 228144645291423602 690041707309747302 191003462832708740 981404451712468361 900400340973685384 507894895830950112 730342794302458267 292630995901...
output:
544144276 818067446 86599466 313726969 18938569 632700031 797497759 781547720 391588017 878181169 310434443 416689342 69020235 460227545 162825045 321960509 604698726 745824316 617383608 26101176 816251396 489328969 613075753 821553025 821486393 270559043 786443427 729545800 129844182 893901263 9674...
result:
ok 100 numbers
Test #4:
score: 0
Accepted
time: 30ms
memory: 4052kb
input:
100 1000000000000000000 999999999999999999 999999999999999998 999999999999999997 999999999999999996 999999999999999995 999999999999999994 999999999999999993 999999999999999992 999999999999999991 999999999999999990 999999999999999989 999999999999999988 999999999999999987 999999999999999986 9999999999...
output:
776755633 305596516 433884536 271324944 255217955 752347893 279777560 954593517 141741201 121847646 925987319 408911539 615371540 395678394 900921829 709870350 988659472 113218064 830032042 970158982 295607870 455576442 901184396 886355576 365985700 530063682 646456471 944296960 543981115 362793239 ...
result:
ok 100 numbers