这题是poj1739的改编版,在那份题解里我用了两种写法,这题的m很大,显然快速幂,BFS所有状态,不过矩阵也相当的大,我算了最大状态是114这么多,所以我优化了快速幂,预存幂矩阵,然后n^2快速幂,跑了600+,那个第一的200+ms是有减少状态么,还是有其他优化方法,我被他时间空间完胜了,Orz。
Run ID | Submit Time | Judge Status | Problem ID | Language | Run Time(ms) | Run Memory(KB) | User Name |
3071991 | 2012-10-02 17:29:15 | Accepted | 3256 | C++ | 670 | 13012 | xym |
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
const int maxn=10001,mod=7777777;
int mov[10]={0,2,4,6,8,10,12,14,16},mp[2<<16],res[130],tem[130],pos;
bool vd[2<<16];
int A[6][30][130][130]={0},B[130][130],len[6],sp[6][2];
struct node
{
int size,head[maxn],next[maxn],sta[maxn];
inline void clear()
{
memset(head,-1,sizeof(head));
size=0;
}
inline void push(int st)
{
int hash=st%maxn;
for(int i=head[hash];i>=0;i=next[i])
{
if(sta[i]==st)
return;
}
sta[size]=st,next[size]=hash;
head[hash]=size++;
}
}dp[2];
inline int getbit(int st,int k){return 3&(st>>mov[k]);}
inline int pybit(int st,int k){return st<<mov[k];}
inline int clrbit(int st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));}
inline int fl(int st,int k,int n)
{
int cnt=1;
for(int i=k+1;i<=n;i++)
{
int e=getbit(st,i);
if(e==2) cnt--;
else if(e==1) cnt++;
if(cnt==0)
return i;
}
}
inline int fr(int st,int k)
{
int cnt=1;
for(int i=k-1;i>=0;i--)
{
int e=getbit(st,i);
if(e==2) cnt++;
else if(e==1) cnt--;
if(cnt==0)
return i;
}
}
inline int find(int st)
{
if(mp[st]==-1)
mp[st]=pos++;
return mp[st];
}
void bfs(int n)
{
int in,out;
queue<int >q;
memset(vd,0,sizeof(vd));
memset(mp,-1,sizeof(mp));
memset(B,0,sizeof(B));
pos=0;
in=pybit(1,0)+pybit(2,n-1);
vd[in]=1,q.push(in);
while(!q.empty())
{
out=q.front();
q.pop();
dp[0].clear();
dp[0].push(out<<2);
int now=0,pre=1;
for(int j=1;j<=n;j++)
{
pre=now,now^=1;dp[now].clear();
for(int k=0;k<dp[pre].size;k++)
{
int l=getbit(dp[pre].sta[k],j-1);
int up=getbit(dp[pre].sta[k],j);
int st=clrbit(dp[pre].sta[k],j-1,j);
if(!l&&!up)
{
if(j<n)
dp[now].push(st|pybit(1,j-1)|pybit(2,j));
}
else if(!l||!up)
{
int e=l==0?up:l;
dp[now].push(st|pybit(e,j-1));
if(j<n)
dp[now].push(st|pybit(e,j));
}
else if(l==1&&up==1)
dp[now].push(st^pybit(3,fl(st,j,n)));
else if(l==2&&up==2)
dp[now].push(st^pybit(3,fr(st,j-1)));
else if(l==2&&up==1)
dp[now].push(st);
else if(j==n&&st==0)
B[find(out)][find(st)]++;
}
}
for(int j=0;j<dp[now].size;j++)
{
in=dp[now].sta[j];
if(!vd[in])
{
vd[in]=1;
q.push(in);
}
B[find(out)][find(in)]++;
}
}
//printf("%d\n",pos);
}
void init()
{
for(int i=0;i<=5;i++)
{
bfs(i+2);
len[i]=pos;
sp[i][0]=find(pybit(1,0)+pybit(2,i+1));
sp[i][1]=find(0);
for(int j=0;j<len[i];j++)
for(int k=0;k<len[i];k++)
A[i][0][j][k]=B[j][k];
for(int j=1;j<30;j++)
{
for(int x=0;x<len[i];x++)
for(int y=0;y<len[i];y++)
{
for(int z=0;z<len[i];z++)
{
LL t=(LL)(A[i][j-1][x][z]*(LL)A[i][j-1][z][y]);
if(t>=mod)t%=mod;
A[i][j][x][y]+=t;
if(A[i][j][x][y]>=mod) A[i][j][x][y]-=mod;
}
}
}
}
}
void q_exp(int k,int e)
{
int cnt=0;
while(k)
{
if(k&1)
{
for(int j=0;j<len[e];j++)
{
tem[j]=0;
for(int k=0;k<len[e];k++)
{
LL t=(LL)res[k]*(LL)A[e][cnt][k][j];
if(t>=mod)t%=mod;
tem[j]+=t;
if(tem[j]>=mod)tem[j]-=mod;
}
}
memcpy(res,tem,sizeof(tem));
}
k>>=1;
cnt++;
}
}
int n,m;
int main()
{
init();
while(~scanf("%d%d",&n,&m))
{
memset(res,0,sizeof(res));
res[sp[n-2][0]]=1;
q_exp(m,n-2);
if(res[sp[n-2][1]]==0)
puts("Impossible");
else
cout<<res[sp[n-2][1]]<<endl;
}
return 0;
}