Cipher Lock Zoj

/*
DP+矩阵连乘
状态P,Q是否与最后节点相同f({0,1},{0,1})
       f(0,0)      f(0,1)    f(1,0)    f(1,1)
f(0,0) P+Q-3或者0    Q-1       P-1       0
f(0,1)  1            P-1        0        P-1
f(1,0)  1            0          Q-1      Q-1
f(1,1)  0            1          1         1
    */
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

typedef long long lld;
const int mod=1234567890;
lld N,P,Q;

struct Node{
	lld x;
	lld p,q;
	bool operator <(const Node &t)const {
		return x<t.x;
	}
}node[20];

lld a[4][4];
lld c[4][4];
lld d[4][4];

void init(){
	memset(c,0,sizeof(c));
	if(P>1 && Q>1)
	c[0][0]=(P+Q-3)%mod;
	c[0][1]=c[2][2]=c[2][3]=(Q-1)%mod;
	c[1][1]=c[0][2]=c[1][3]=(P-1)%mod;
	c[1][0]=c[2][0]=c[3][1]=c[3][2]=c[3][3]=1;
	
}

void Mul(lld c[][4],lld a[][4]){
	int i,j,k;
	memset(d,0,sizeof(d));
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			for(k=0;k<4;k++){
				d[i][j]+=c[i][k]*a[k][j]%mod;
				d[i][j]%=mod;
			}
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			a[i][j]=d[i][j];
}

lld Gao(lld b){
	lld ret=1;
	init();
	while(b){
		if(b&1)Mul(c,a);
		Mul(c,c);
		b>>=1;
	}
	ret=a[3][0];
	return ret;
}

int main(){
	int i,j;
	while(scanf("%lld%lld%lld",&N,&P,&Q)!=EOF){
		for(i=0;i<8;i++)
			scanf("%lld%lld%lld",&node[i].x,&node[i].p,&node[i].q);
		sort(node,node+8);
		node[8]=node[0];
		node[8].x=N+node[0].x;
		lld ans=1;
		for(i=1;i<=8;i++){
			memset(a,0,sizeof(a));
			if(node[i].p==node[i-1].p && node[i].q==node[i-1].q)
				a[3][0]=1;
			else if(node[i].p!=node[i-1].p && node[i].q==node[i-1].q)
				a[1][0]=1;
			else if(node[i].p==node[i-1].p && node[i].q!=node[i-1].q)
				a[2][0]=1;
			else
				a[0][0]=1;
			lld tp=node[i].x-node[i-1].x;
			ans=(ans*Gao(tp))%mod;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值