[ARC182C] Sum of Number of Divisors of Product

WrongAnswer_90發表於2024-08-13

My Blogs

[ARC182C] Sum of Number of Divisors of Product

見過一萬遍的套路啊啊啊啊啊。

首先如果序列乘積是 \(\prod c_i^{p_i}\),答案就是 \(\prod (p_i+1)\)\(M\) 以內的質數個數只有 \(6\) 個:\(\{2,3,5,7,11,13\}\)

然後考慮這個式子的組合意義:對於每個質因子,可以看成在其每次出現的時候可以選它,這樣每個質因子需要恰好被選一次。對於 \(+1\) 的問題可以一開始就把所有無論選還是不選的答案設成 \(1\)

狀壓上面這個東西,\(0\) 表示這一位還沒選,\(1\) 表示選了。預處理轉移矩陣,因為要求序列長度 \(\leq n\),所以還要開一維記答案,總複雜度 \(\mathcal O((2^6+1)^3\log n)\)

int n,m,v[6];
struct Matrix{int f[65][65];Matrix(){memset(f,0,sizeof(f));}}M;
struct Vector{int f[65];Vector(){memset(f,0,sizeof(f));}}F;
inline Matrix operator *(const Matrix x,const Matrix y)
{
	Matrix z;
	for(int i=0;i<65;++i)for(int j=0;j<65;++j)for(int k=0;k<65;++k)
	Madd(z.f[i][j],Cmul(x.f[i][k],y.f[k][j]));
	return z;
}
inline Vector operator *(const Vector x,const Matrix y)
{
	Vector z;
	for(int j=0;j<65;++j)for(int k=0;k<65;++k)
	Madd(z.f[j],Cmul(x.f[k],y.f[k][j]));
	return z;
}
const int P[6]={2,3,5,7,11,13};
inline void mian()
{
	read(n,m),M.f[64][64]=1;
	for(int i=1;i<=m;++i)
	{
		int x=i;memset(v,0,sizeof(v));
		for(int j=0;j<6;++j)while(x%P[j]==0)++v[j],x/=P[j];
		for(int j=0;j<64;++j)
		{
			for(int k=j;;k=(k-1)&j)
			{
				int s=1;
				for(int l=0;l<6;++l)if((k^j)>>l&1)Mmul(s,v[l]);
				Madd(M.f[k][j],s);
				if(j==63)Madd(M.f[k][64],s);
				if(!k)break;
			}
		}
	}
	for(int i=0;i<64;++i)F.f[i]=1;
	for(;n;n>>=1,M=M*M)if(n&1)F=F*M;
	write(F.f[64]);
}