记录编号 256346 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015]香蕉 最终得分 100
用户昵称 GravatarAglove 是否通过 通过
代码语言 C++ 运行时间 0.358 s
提交时间 2016-04-30 08:41:52 内存使用 152.94 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;

typedef unsigned long long LL;
const int mod=998244353;
int n,m,N,L;
LL f[20][1000010];
LL s[20];
LL g[20][20];
int id[20][2],cnt;
struct Matrix{
	LL a[42][42];
	void clear(){memset(a,0,sizeof(a));}
}A,ans;
void UPD(LL &a){if(a>=mod)a-=mod;}
Matrix operator *(const Matrix &A,const Matrix &B){
	Matrix C;C.clear();
	for(int i=1;i<=cnt;++i){
		for(int j=1;j<=cnt;++j){
			int sum=0;
			for(int k=1;k<=cnt;++k){
				C.a[i][j]=C.a[i][j]+A.a[i][k]*B.a[k][j];
				sum++;
				if(sum==10)sum=0,C.a[i][j]%=mod;
			}C.a[i][j]%=mod;
		}
	}return C;
}
Matrix pow_mod(Matrix v,int p){
	Matrix tmp;tmp.clear();
	for(int i=1;i<=cnt;++i)tmp.a[i][i]=1;
	while(p){
		if(p&1)tmp=tmp*v;
		v=v*v;p>>=1;
	}return tmp;
}
void build_Matrix(){
	for(int i=1;i<=L;++i){
		id[i][0]=++cnt;
		id[i][1]=++cnt;
	}
	for(int i=1;i<=cnt-2;++i)A.a[i+2][i]=1;
	for(int i=1;i<=L;++i){
		int j=(L+1-i);
		A.a[id[i][(j&1)^1]][cnt-1]=s[j];
		A.a[id[i][j&1]][cnt]=s[j];
	}g[0][0]=1;
	for(int i=1;i<=L;++i){
		for(int j=1;j<=i;++j){
			g[i][0]=g[i][0]+g[i-j][(j&1)^1]*s[j]%mod;
			g[i][1]=g[i][1]+g[i-j][j&1]*s[j]%mod;
			UPD(g[i][0]);UPD(g[i][1]);
		}
	}
	for(int i=1;i<=L;++i){
		ans.a[1][id[i][0]]=g[i][0];
		ans.a[1][id[i][1]]=g[i][1];
	}return;
}
int main(){
	freopen("Banana.in","r",stdin);
	freopen("Banana.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(N=1;N<=m;N<<=1,L++);
	for(int i=1;i<=m;++i)f[1][i]=1;
	s[1]=m;
	for(int i=1;i<L;++i){
		for(int k=1;k<=m;++k){
			for(int j=k+k;j<=m;j+=k){
				f[i+1][j]=f[i+1][j]+f[i][k];
				UPD(f[i+1][j]);
			}
		}
		for(int j=1;j<=m;++j){
			s[i+1]=s[i+1]+f[i+1][j];
			UPD(s[i+1]);
		}
	}
	build_Matrix();
	A=pow_mod(A,n-1);ans=ans*A;
	LL S=(ans.a[1][1]-ans.a[1][2]+mod)%mod;
	printf("%lld\n",S);
	return 0;	
}