记录编号 387044 评测结果 AAAAAAA
题目名称 [UVa 11276] 神奇的七 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 12.982 s
提交时间 2017-03-25 15:42:11 内存使用 85.73 MiB
显示代码纯文本
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef unsigned long long ull;
const int N=330;
ull n;
int q[N],tag[1<<16],size;
typedef pair<int,int> pr;
struct matrix{
	int a[N][N];
	vector<pr> E;
	matrix(){clear();}
	void clear(){
		memset(a,0,sizeof a);
		E.clear();
	}
	void set(int x,int y,int val){
		E.push_back(pr(x,y));
		a[x][y]=val;
	}
	void operator *= (const matrix &x){
		static matrix Ans;
		Ans.clear();
		static ull ans[N][N]={0};
		for (int i=E.size()-1;i>=0;i--){
			int X=E[i].first,Y=E[i].second,val=a[X][Y];
			for (int k=0;k<N;k++) ans[X][k]+=val*x.a[Y][k];
		}
		for (int i=0;i<N;i++)
		for (int j=0;j<N;j++)
		if (ans[i][j]){
			Ans.set(i,j,ans[i][j]%10000);
			ans[i][j]=0;
		}
		*this=Ans;
	}
}x1,x2,x3,a1,a2,a3,E,now,ans;
matrix p[3][64];
void mi(int tp,ull y){
	for (int i=0;i<64;i++)
		if (y>>i&1) ans*=p[tp][i];
}
void dfs1(int p,int S,int now){//完美匹配 
	if (p==7){
		x1.set(S,now,1);
		return;
	}
	if (S>>p&1) dfs1(p+1,S,now);
	else{
		dfs1(p+1,S,now|(1<<p));//向后匹配 
		if (p<6&&!(S>>(p+1)&1)) dfs1(p+2,S,now);//向上匹配 
	}
}
void set(int &x,int p,int tp){
	x&=~(3<<(p<<1));
	x|=(tp<<(p<<1));
}
int get(int x,int p){return (x>>(p<<1))&3;}
int stack[N],top,d[N][N];
void dfs(int p,int S,int cnt){
	if (cnt<0) return;
	if (p>7){
		if (cnt) return;
		for (int i=0;i<8;i++){
			int tp=get(S,i);
			if (tp==1) stack[++top]=i;
			if (tp==2){
				d[size][i]=stack[top];
				d[size][stack[top--]]=i;
			}
		}
		q[size++]=S;
		tag[S]=size-1;
		return;
	}
	set(S,p,0);dfs(p+1,S,cnt);
	set(S,p,1);dfs(p+1,S,cnt+1);
	set(S,p,2);dfs(p+1,S,cnt-1);
}
void work(int j,bool TP){//TP=0表示哈密顿圈,TP=1表示生成子图 
	now.clear();
	for (int k=0;k<size;k++){
		int S=q[k],right=get(S,j),down=get(S,j+1);
		if (!right&&!down){
			set(S,j,1);set(S,j+1,2);
			now.set(k,tag[S],1);
		}
		else if (right==1&&down==2){
			if (TP){
				set(S,j,0);set(S,j+1,0);
				now.set(k,tag[S],1);
			}
		}
		else if ((!right)^(!down)){
			int p=right|down;
			set(S,j,p);set(S,j+1,0);now.set(k,tag[S],1);
			set(S,j,0);set(S,j+1,p);now.set(k,tag[S],1);
		}
		else{
			int l=d[k][j],r=d[k][j+1];
			if (l>r) swap(l,r);
			set(S,l,1);set(S,r,2);
			set(S,j,0);set(S,j+1,0);
			now.set(k,tag[S],1);
		}
	}
}
void pushdown(){
	now.clear();
	for (int k=0;k<size;k++){
		int S=q[k];
		if (!get(S,7)) now.set(k,tag[S<<2],1);
	}
}
void init(){
	//完美匹配初始化 
	for (int i=0;i<128;i++) dfs1(0,i,0);
	a1.set(0,0,1);
	//插头dp初始化 
	dfs(0,0,0);
	for (int i=0;i<size;i++) E.set(i,i,1);
	//哈密顿圈初始化 
	a2.set(0,0,1);
	for (int i=0;i<6;i++) work(i,0),a2*=now;
	x2=E;
	work(6,0);x2*=now;
	pushdown();x2*=now;
	for (int i=0;i<6;i++) work(i,0),x2*=now;
	//生成子图初始化 
	x3=E;
	for (int i=0;i<7;i++) work(i,1),x3*=now;
	pushdown();x3*=now;
	a3.set(0,0,1);
	//生成矩阵的幂 
	p[0][0]=x1;p[1][0]=x2;p[2][0]=x3;
	for (int i=1;i<64;i++)
	for (int j=0;j<3;j++)
		p[j][i]=p[j][i-1],p[j][i]*=p[j][i];
}
int main()
{
	freopen("magicalseven.in","r",stdin);
	freopen("magicalseven.out","w",stdout);
	init();
	int end=0;
	set(end,6,1);set(end,7,2);
	while (cin>>n){
		int Ans=0;
		ans=a1;mi(0,n);
		Ans+=ans.a[0][0];
		ans=a2;mi(1,n-1);
		Ans+=ans.a[0][tag[end]];
		if (n>1){
			ans=a3;mi(2,n);
			Ans+=ans.a[0][tag[0]];
		}
		printf("%04d\n",Ans%10000);
	}
	return 0;
}