タイトル説明
問題の解決策
八のSBのタイトル
もちろん、あなたのような圧力を考えることができ
列挙現在の幅\(I \) 、提供\(F [S] \)の現在の幅が選択される基を表し縦辺状態をs
次に、設定\(Gは[S1] [S2] \)列挙中間体、プログラムは、s1とs2の状態に移行表す横エッジ S3のセットを
明らかではない正当な本実施形態、すなわち、正方形側の四辺である(S1 \&S2 \&\ (S3 + 2 ^ {I-1})\&((S3 << 1)+1)\)
もし、i番目の格子の四辺の存在のみ\(S1 \)の\(I-1 \)ビット(すなわち\(^ {2} 1-i)は\)、\ (S2 \)の\ (I-1 \)ビット、\(S3 \)の\(I-2 \)ビットと\(I-1 \)ビットが存在するので、上記の式があります
(dpが簡単にシフトし、それがハングアップします
加速する時間を取ります
コード
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 1000000007
using namespace std;
int p[8]={0,1,2,4,8,16,32,64};
int w[8];
long long f[2][128];
long long a[128][128];
long long b[128][128];
long long c[128][128];
int i,j,k,l,I,L,i2,i3;
int main()
{
// freopen("51nod1730.in","r",stdin);
// freopen("51nod1730.out","w",stdout);
fo(i,1,7)
scanf("%d",&w[i]);
i2=0;
f[0][0]=1;
fo(I,1,7)
{
i3=i2^1;
memset(f[i3],0,sizeof(f[i3]));
L=p[I]*2-1;
fo(i,0,p[I]-1)
f[i3][i|p[I]]=f[i2][i];
i2=i3;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
fo(i,0,L)
{
fo(j,0,L)
{
fo(k,0,p[I]-1)
if (!(i&j&((k<<1)+1)&(k+p[I])))
++b[i][j];
}
}
fo(i,0,L)
a[i][i]=1;
while (w[I])
{
if (w[I]&1)
{
memset(c,0,sizeof(c));
fo(i,0,L)
{
fo(j,0,L)
{
fo(k,0,L)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod;
}
}
fo(i,0,L)
{
fo(j,0,L)
a[i][j]=c[i][j];
}
}
memset(c,0,sizeof(c));
fo(i,0,L)
{
fo(j,0,L)
{
fo(k,0,L)
c[i][j]=(c[i][j]+b[i][k]*b[k][j])%mod;
}
}
fo(i,0,L)
{
fo(j,0,L)
b[i][j]=c[i][j];
}
w[I]>>=1;
}
i3=i2^1;
memset(f[i3],0,sizeof(f[i3]));
fo(j,0,L)
{
fo(k,0,L)
f[i3][j]=(f[i3][j]+f[i2][k]*a[k][j])%mod;
}
i2=i3;
}
printf("%lld\n",f[i2][p[7]*2-1]);
fclose(stdin);
fclose(stdout);
return 0;
}