The paper has N grids in a line. Each time he will fill a grid with one of the six colors. All grids needs to be filled. To make his drawing more beautiful, Skywind decided to draw symmetrically. Moreover, as he hates sorting, Skywind will never come up with the situation where all colors are in their original order. So he won't draw red-orange-yellow-green-blue-violet in a continuous way. And to make his drawing clearer, he won't paint the same color in adjacent grids.
Given N, you are asked to calculate the number of ways that Skywind can complete his drawing. As the answer might be very large, just output the number MOD 112233.
2 5
0 150
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cctype>
#include<map>
using namespace std;
const int MOD=112233;
const int maxn=500;
struct Node
{
int flag;//序号
int id;//在静态链表中的位置
Node* next[6];
Node* fail;
};
Node temp[maxn];
int tp;
int n;
int len;
const int kind=6;
Node* root;
void reset(Node* p)
{
p->flag=0;p->id=tp-1;
for(int i=0;i<kind;i++) p->next[i]=NULL;
p->fail=root;
if(p==root) p->fail=NULL;
}
void init()
{
tp=0;
root=&temp[tp++];
reset(root);
}
void insert(char* word)
{
Node* p=root;
for(int i=0;word[i];i++)
{
int x=word[i]-'0';
if(p->next[x]==NULL)
{
p->next[x]=&temp[tp++];
reset(p->next[x]);
}
p=p->next[x];
}
p->flag=1;
}
Node* que[maxn*4];
int front,rear;
void DFA()
{
Node* p=root;
front=rear=0;
que[rear++]=p;
while(front<rear)
{
Node* t=que[front++];
for(int i=0;i<kind;i++)
{
Node* cnt=t->next[i];
if(cnt!=NULL)
{
Node* fath=t->fail;
while(fath!=NULL&&fath->next[i]==NULL)
{
fath=fath->fail;
}
if(fath!=NULL)
{
cnt->fail=fath->next[i];
}
else
{
cnt->fail=p;
}
que[rear++]=cnt;
}
}
}
}
__int64 a[maxn][maxn];
int r;
//a r*r 求a^len
void toMatrix()
{
r=rear;
memset(a,0,sizeof(a));
Node* fath;
for(int i=0;i<rear;i++)
{
Node* p=&temp[i];
if(p->flag) continue;
for(int j=0;j<kind;j++)
{
Node* cnt=p->next[j];
if(cnt!=NULL)
{
int mark=1;//important
for(fath=cnt;fath!=NULL;fath=fath->fail)
{
if(fath->flag) {
mark=0;
break;
}
}
if(mark)
{
int k=cnt->id;
a[i][k]++;
}
}
else
{
fath=p->fail;
while(fath!=NULL&&fath->next[j]==NULL)
{
fath=fath->fail;
}
if(fath!=NULL)
{
cnt=fath->next[j];
int mark=1;//important
for(fath=cnt;fath!=NULL;fath=fath->fail)
{
if(fath->flag) {
mark=0;
break;
}
}
if(mark)
{
int k=cnt->id;
a[i][k]++;
}
}
else
{
cnt=root;
a[i][0]++;
}
}
}
}
}
__int64 t[maxn][maxn],tmp[maxn][maxn],b[maxn][maxn];
void multiply(__int64 a[][maxn],__int64 b[][maxn],__int64 c[][maxn])
{
for(int i=0;i<r;i++)
{
for(int j=0;j<r;j++)
{
__int64 cnt=0;
for(int k=0;k<r;k++)
{
cnt+=a[i][k]*b[k][j];
cnt%=MOD;
}
c[i][j]=cnt;
}
}
}
void matrixPow(__int64 a[][maxn],int p)//p>1
{
if(p==1)
{
for(int i=0;i<r;i++) for(int j=0;j<r;j++) a[i][j]=b[i][j];
return ;
}
if(p&1)
{
matrixPow(a,p/2);
multiply(a,a,tmp);
multiply(b,tmp,t);
for(int i=0;i<r;i++) for(int j=0;j<r;j++) a[i][j]=t[i][j];
}
else
{
matrixPow(a,p/2);
multiply(a,a,t);
for(int i=0;i<r;i++) for(int j=0;j<r;j++) a[i][j]=t[i][j];
}
}
int main()
{
//freopen("outwa.txt","w",stdout);
init();
insert("012345");insert("543210");
insert("00");insert("11");insert("22");
insert("33");insert("44");insert("55");
DFA();
toMatrix();
for(int i=0;i<r;i++) for(int j=0;j<r;j++) b[i][j]=a[i][j];
while(scanf("%d",&len)==1)
{
if(len%2==0)
{
printf("0\n");continue;
}
matrixPow(a,len/2+1);//a^len
int cnt=0;
for(int i=0;i<r;i++) cnt+=a[0][i],cnt%=MOD;
printf("%d\n",cnt);
}
return 0;
}