QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#204021#874. Long Grid CoveringwoshiluoTL 33ms3104kbC++205.1kb2023-10-06 23:56:192023-10-06 23:56:21

Judging History

你现在查看的是最新测评结果

  • [2023-10-06 23:56:21]
  • 评测
  • 测评结果:TL
  • 用时:33ms
  • 内存:3104kb
  • [2023-10-06 23:56:19]
  • 提交

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 {/*{{{*/
	int cur;
	ModInt( ll _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;
}
int32_t full_pow( const int32_t cur ) {
	return 1 << cur;
}
int32_t set_bit( const int32_t cur, const int32_t pos ) {
	return cur | full_pow(pos);
}
bool chk_pos( const int32_t cur, const int32_t pos ) {
	return ( cur >> pos ) & 1;
}

ModInt f[P], g[P][32];

const int LP = 1 << 6;
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( int 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( int i = 0; i < full_pow(6); i ++ ) {
		for( int 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 ) );
			p.a[i][j] += f[mask];
		}
	}

	for( int i = 0; i < full_pow(6); i ++ ) {
		for( int j = 0; j < full_pow(6); j ++ ) {
			if( p.a[i][j].cur ) {
				if( i != 0 && ( i <= 7 || std::__popcount(i) < 3 ) ) {
					p.a[i][j] = 0;
				}
				else {
#ifdef woshiluo
					printf( "(%d,%d) = %3d\n", i, j, p.a[i][j].cur );
#endif
				}
			}
		}
	}

	int T = read<int>();
	while( T -- ) {
		const int64_t n = read<ll>();
		Matrix a;
		a.a[0][0] = 1;
		a *= pow( p, n );
		a.a[0][0].output();
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 33ms
memory: 3104kb

input:

4
1
2
3
10

output:

1
3
10
8266

result:

ok 4 number(s): "1 3 10 8266"

Test #2:

score: -100
Time Limit Exceeded

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:


result: