結果
問題 | No.579 3 x N グリッド上のサイクルのサイズ(hard) |
ユーザー |
|
提出日時 | 2017-10-14 00:19:09 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 5 ms / 2,000 ms |
コード長 | 4,206 bytes |
コンパイル時間 | 1,448 ms |
コンパイル使用メモリ | 124,864 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2024-11-17 11:54:47 |
合計ジャッジ時間 | 3,634 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 80 |
ソースコード
#define _USE_MATH_DEFINES#include <cstdio>#include <iostream>#include <sstream>#include <fstream>#include <iomanip>#include <algorithm>#include <cmath>#include <complex>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <set>#include <map>#include <bitset>#include <numeric>#include <limits>#include <climits>#include <cfloat>#include <functional>#include <iterator>using namespace std;const int MOD = 1000000007;template <class T>vector<vector<T> > matrixProduct(const vector<vector<T> >& x, const vector<vector<T> >& y){int a = x.size();int b = x[0].size();int c = y[0].size();vector<vector<T> > z(a, vector<T>(c, 0));for(int i=0; i<a; ++i){for(int j=0; j<c; ++j){for(int k=0; k<b; ++k){z[i][j] += x[i][k] * y[k][j];z[i][j] %= MOD;}}}return z;}template <class T>vector<vector<T> > matrixPower(const vector<vector<T> >& x, long long k){int n = x.size();vector<vector<T> > y(n, vector<T>(n, 0));for(int i=0; i<n; ++i)y[i][i] = 1; // 積の単位元vector<vector<T> > z = x;while(k > 0){if(k & 1)y = matrixProduct(y, z);z = matrixProduct(z, z);k >>= 1;}return y;}const vector<string> STATE ={"____","AA__","_AA_","__AA","A_A_","_A_A","A__A","AABB","ABBA"};const int STATE_NUM = STATE.size();const char EMPTY = '_';const string EMPTY_STR(4, EMPTY);string normalizeState(const string& s){char newChar = 'A';map<int, int> to;to[EMPTY] = EMPTY;string t;for(char c : s){if(to.find(c) == to.end()){to[c] = newChar;++ newChar;}t.push_back(to[c]);}return t;}int main(){long long n;cin >> n;vector<vector<long long> > mat(STATE_NUM*2+1, vector<long long>(STATE_NUM*2+1, 0));mat[STATE_NUM*2][STATE_NUM*2] = 1;for(int a=0; a<STATE_NUM; ++a){const string& s = STATE[a];bitset<4> upper;for(int i=0; i<4; ++i)upper[i] = (s[i] != EMPTY);for(int i=0; i<(1<<3); ++i){bitset<5> side(i << 1);bool ng = false;int cnt = 0;for(int j=0; j<4; ++j){if(upper[j] && side[j] && side[j+1])ng = true;if(upper[j] || side[j] || side[j+1])++ cnt;}if(ng)continue;string t = s;int sameCnt = 0;char newChar = 'Z';for(int j=0; j<4; ++j){if(!side[j]){int k = j;while(side[k+1])++ k;if(j < k){if(s[j] == EMPTY && s[k] == EMPTY){t[j] = t[k] = newChar;-- newChar;}else if(s[j] == EMPTY || s[k] == EMPTY){swap(t[j], t[k]);}else if(s[j] == s[k]){t[j] = t[k] = EMPTY;++ sameCnt;}else{replace(t.begin(), t.end(), s[j], s[k]);t[j] = t[k] = EMPTY;}}}}if(sameCnt >= 2 || (sameCnt == 1 && t != EMPTY_STR))continue;if(t == EMPTY_STR && cnt > 0){++ mat[STATE_NUM*2][a+STATE_NUM];mat[STATE_NUM*2][a] += cnt;}else{t = normalizeState(t);int b = find(STATE.begin(), STATE.end(), t) - STATE.begin();++ mat[b][a];++ mat[b+STATE_NUM][a+STATE_NUM];mat[b+STATE_NUM][a] += cnt;}}}mat = matrixPower(mat, n+1);cout << mat[STATE_NUM*2][0] << endl;return 0;}