結果
| 問題 |
No.569 3 x N グリッドのパスの数
|
| コンテスト | |
| ユーザー |
btk
|
| 提出日時 | 2017-09-14 16:10:12 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 3 ms / 2,000 ms |
| コード長 | 3,050 bytes |
| コンパイル時間 | 2,697 ms |
| コンパイル使用メモリ | 202,736 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-11-07 19:51:11 |
| 合計ジャッジ時間 | 4,394 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 60 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define CIN_ONLY if(1)
struct cww{cww(){
CIN_ONLY{
ios::sync_with_stdio(false);cin.tie(0);
}
}}star;
#ifdef BTK
#define DEBUG if(1)
#else
#define DEBUG if(0)
#endif
#define fin "\n"
#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
#define pb push_back
#define REC(ret, ...) std::function<ret (__VA_ARGS__)>
template <typename T>inline bool chmin(T &l,T r)
{bool a=l>r;if(a)l=r;return a;}
template <typename T>inline bool chmax(T &l,T r)
{bool a=l<r;if(a)l=r;return a;}
template <typename T>
istream& operator>>(istream &is,vector<T> &v){
for(auto &it:v)is>>it;
return is;
}
#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
typedef LL D;
#define REP4(i,n) for(int i=0;i<n;i+=4)
#define S 12
int sz=S;
struct M{
D v[S][S];
D& operator()(int i,int j){
return v[i][j];
}
}mat[64];
const int mod=1e9+7;
void mat_mul(M &a,M& b,M &c){
REP(i,sz)REP(j,sz)c(i,j)=0;
D sum[4],tmp;
REP(k,sz){
REP4(i,sz){
sum[0]=a(i,k);
sum[1]=a(i+1,k);
sum[2]=a(i+2,k);
sum[3]=a(i+3,k);
REP(j,sz){
tmp=b(k,j);
c(i,j)+=sum[0]*tmp%mod;
c(i+1,j)+=sum[1]*tmp%mod;
c(i+2,j)+=sum[2]*tmp%mod;
c(i+3,j)+=sum[3]*tmp%mod;
}
}
}
REP(i,sz)REP(j,sz)c(i,j)%=mod;
}
map<string,int> z;
map<string,vector<string>> g;
map<string,vector<string>> rg;
inline string rev(string s){
reverse(ALL(s));
return s;
}
int M=0;
void init(){
g["0123"]={"0123","1023","0001"};
g["1023"]={"1023","0001","0123","1203"};
g["1203"]={"1203","1023","1230","0001","0010"};
g["1230"]={"1230","1203","0010","0001"};
g["1000"]={"1000","0100","0010","0001","1230","1203","1023","0123"};
g["0100"]={"1000","0100","0010","0001","0123","1023"};
for(auto &it:g){
vector<string> x;
for(auto s:it.se)x.pb(rev(s));
rg[rev(it.fi)]=x;
}
for(auto &it:g)z[it.fi]=M++;
for(auto &it:rg)z[it.fi]=M++;
for(auto &it:g){
int v=z[it.fi];
for(auto &jt:it.se){
int u=z[jt];
mat[0](v,u)=1;
}
}
for(auto &it:rg){
int v=z[it.fi];
for(auto &jt:it.se){
int u=z[jt];
mat[0](v,u)=1;
}
}
REP(i,61)mat_mul(mat[i],mat[i],mat[i+1]);
}
LL calc_ret(vector<LL> v){
LL ret=0;
ret+=v[z["0001"]];
return ret%mod;
}
int main(){
init();
LL N;
cin>>N;N++;
LL ret=0;
vector<LL> v(M,0);
v[z["1000"]]=1;
int id=0;
while(N){
vector<LL> nxt(M,0);
if(N&1){
REP(i,M)REP(j,M)
nxt[j]+=v[i]*mat[id](i,j);
REP(i,M)nxt[i]%=mod;
swap(v,nxt);
}
id++;
N>>=1;
}
cout<<calc_ret(v)<<endl;
return 0;
}
btk