记录编号 255653 评测结果 AAAAAAAAAA
题目名称 2290.[HZOI 2015]香蕉 最终得分 100
用户昵称 Aglove 是否通过 通过
代码语言 C++ 运行时间 2.959 s
提交时间 2016-04-28 15:31:55 内存使用 4.61 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

typedef unsigned long long LL;
const int maxn=100010;
const int base=13331;
const int mode=100007;
const int mod=998244353;
int n,m,BA;
bool vis[maxn];
bool check[maxn];
int p[maxn],cnt=0;
int S[maxn],top=0;
int blo[maxn],tot=0;
int Num[maxn];

struct HASHMAP{
	int h[mode+10],cnt;
	int next[maxn],idx[maxn];
	LL st[maxn];
	int ask(LL hash){
		int key=hash%mode;
		if(key<0)key+=mode;
		for(int i=h[key];i;i=next[i]){
			if(st[i]==hash)return idx[i];
		}
		++cnt;next[cnt]=h[key];h[key]=cnt;
		st[cnt]=hash;idx[cnt]=++tot;
		return idx[cnt];
	}
}H;
struct Matrix{
	LL a[161][161];
	void clear(){memset(a,0,sizeof(a));}
	void print(){
		for(int i=1;i<=tot;++i){
			for(int j=1;j<=tot;++j){
				printf("%lld ",a[i][j]);
			}printf("\n");
		}printf("\n");
	}
}A,ans;
void Get_Prime(){
	for(int i=2;i<=m;++i){
		if(!vis[i])p[++cnt]=i;
		for(int j=1;j<=cnt;++j){
			if(1LL*p[j]*i>m)break;
			vis[p[j]*i]=true;
			if(i%p[j]==0)break;
		}
	}return;
}
void Get_FJ(int x){
	int u=x;top=0;
	for(int i=1;i<=cnt;++i){
		if(1LL*p[i]*p[i]>x)break;
		if(x%p[i]==0){
			int cnt=0;
			while(x%p[i]==0)x/=p[i],cnt++;
			S[++top]=cnt;
		}
	}
	if(x!=1)S[++top]=1;
	sort(S+1,S+top+1);
	LL HA=0;
	for(int i=1;i<=top;++i)HA=HA*base+S[i];
	blo[u]=H.ask(HA);Num[blo[u]]++;
}
void build_Matrix(){
	for(int i=1;i<=m;++i){
		if(!check[blo[i]]){
			check[blo[i]]=true;
			for(int j=1;j<=m;++j){
				if(i<=j||i%j>0)A.a[blo[j]][blo[i]]++;
			}
		}
	}return;
}
Matrix operator *(const Matrix &A,const Matrix &B){
	Matrix C;C.clear();
	for(int i=1;i<=tot;++i){
		for(int j=1;j<=tot;++j){
			for(int u=0;u<=BA;++u){
				int R=min((u+1)*10,tot);
				for(int k=u*10+1;k<=R;++k){
					C.a[i][j]=C.a[i][j]+A.a[i][k]*B.a[k][j];
				}C.a[i][j]%=mod;
			}
		}
	}return C;
}
Matrix pow_mod(Matrix v,int p){
	Matrix tmp;tmp.clear();
	for(int i=1;i<=tot;++i)tmp.a[i][i]=1;
	while(p){
		if(p&1)tmp=tmp*v;
		v=v*v;p>>=1;
	}return tmp;
}
int main(){
	freopen("Banana.in","r",stdin);
	freopen("Banana.out","w",stdout);
	scanf("%d%d",&n,&m);
	Get_Prime();
	for(int i=1;i<=m;++i)Get_FJ(i);
	build_Matrix();BA=tot/10;
	A=pow_mod(A,n-1);
	for(int i=1;i<=tot;++i)ans.a[1][i]=1;
	ans=ans*A;
	LL S=0;
	for(int i=1;i<=tot;++i){
		S=S+ans.a[1][i]*Num[i]%mod;
		if(S>=mod)S-=mod;
	}printf("%lld\n",S);
	return 0;
}