Codeforces 1152F2 Neko Rules the Catniverse (Large Version)

105 篇文章 0 订阅
86 篇文章 0 订阅

题目
题意:
n ( &lt; = 1 0 9 ) n(&lt;=10^9) n(<=109)个星球中,一个人能从x号星球到y号星球当且仅当y没有被访问过并且 1 &lt; = y &lt; = x + m ( m &lt; = 4 ) 1&lt;=y&lt;=x+m(m&lt;=4) 1<=y<=x+m(m<=4)
求走 k ( &lt; = 12 ) k(&lt;=12) k(<=12)步的方案数。

发现按走的顺序 d p dp dp不好记录状态。
那就强行按从大编号往小编号 d p dp dp
在考虑把当前编号 x x x(为最小编号)插入行走序列的方案数,
也就是记一下 x + 1 , x + 2 , . . , x + m x+1,x+2,..,x+m x+1,x+2,..,x+m是否被走过(那么就可以把 x x x插到 x + k x+k x+k前面),
这个就可以状压了然后矩阵加速了。

AC Code:

#include<bits/stdc++.h>
#define maxn 250
#define mod 1000000007
using namespace std;

int n,k,m;
int S,M;
int bit[maxn];

struct mat{
	int a[maxn][maxn];
	mat (int d=0){memset(a,0,sizeof a);for(int i=0;i<maxn;i++) a[i][i]=d;}
	mat operator *(const mat &B)const{ 
		mat ret = mat(0);
		for(int i=0;i<S;i++)
			for(int j=0;j<S;j++) if(a[i][j])
				for(int k=0;k<S;k++) if(B.a[j][k])
					ret.a[i][k] = (ret.a[i][k]+ a[i][j] * 1ll * B.a[j][k])%mod;
		return ret;
	}
}A;

mat Pow(mat base,int k){
	mat ret = mat(1);
	for(;k;k>>=1,base=base*base)
		if(k&1)
			ret=ret*base;
	return ret;
}

int main(){
	scanf("%d%d%d",&n,&k,&m);
	M = 1<<m;
	S = (k+1) * M;
	for(int sta=1;sta<M;sta++)
		bit[sta] = bit[sta-(sta&-sta)] + 1;
	for(int sta=0;sta<M;sta++)
		for(int i=0;i<=k;i++){
			A.a[i*M+sta][i*M+((sta<<1)&(M-1))]++;
			if(i<k)A.a[i*M+sta][(i+1)*M+((sta<<1)&(M-1))+1]+=bit[sta]+1; 
		}
	A = Pow(A,n);
	int ans = 0;
	for(int sta=0;sta<M;sta++){
		ans = (ans + A.a[0][k*M+sta])%mod;
	}
	printf("%d\n",(ans+mod)%mod);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值