luogu P4917 天守阁的地板
Posted study-ysj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P4917 天守阁的地板相关的知识,希望对你有一定的参考价值。
题目描述:
设 \(F(i,j)\) 表示用 \(i*j\) 大小的矩形 不旋转拼成一个边长任意的正方形所需要的最小块数
给出 \(T\) 组 \(n\),求每次询问中 \(\Pi_i=1^n \Pi_j=1^n F(i,j)\)
\(n \leq 10^6,T \leq 10^3\)
题解
一眼SB题不是吗
先考虑单个询问的情况,可以得到如下结论:
用\(a*b\)规格的地板摆成的正方形的边长最小是\(lcm(a,b)\)(木板不允许旋转),所以需要最小的木板数量是\(\fraclcm(a,b)a*\fraclcm(a,b)b\)
问题中说要把所有可能的\((a,b)\)的答案求乘积,那么问题就转换成了求\[\Pi_i=1^n\Pi_j=1^n\fraclcm(i,j)^2i*j\]
首先你必须知道
\[lcm(i,j)*gcd(i,j)=i*j\](唯一分解后易证)
因此
\[\Pi_i=1^n\Pi_j=1^n\fraclcm(i,j)^2i*j=\Pi_i=1^n\Pi_j=1^n\fraci*jgcd(i,j)^2\]
先考虑分子:
\[\Pi_i=1^n\Pi_j=1^ni*j=(1^2n*2^2n*...*n^2n)=(n!)^2n\]
所以可以先\(O(n)\)预处理出阶乘\(fac(i)\),用快速幂\(O(logn)\)算出分子
接下来考虑分母
为了方便,可以先求出\[\Pi_i=1^n\Pi_j=1^ngcd(i,j)\]
再平方
考虑枚举\(d\),那么我们求出对于每个\(d\)有多少对\((i,j)\)满足\(gcd(i,j)=d\)再套用快速幂即可
显然,\(i,j\)都是\(d\)的倍数是必要条件,所以设\(i=k_1d,j=k_2d(k1,k2≤\lfloor \fracnd \rfloor)\)
那么当且仅当\(gcd(k1,k2)=1\)即\(k1,k2\)互质时符合\(gcd(i,j)=d\)的条件(否则\(gcd\)可以扩大为\(d*gcd(k1,k2)\))
不妨令 \(k1>k2\),那么符合条件的点对数 为每个在范围内的\(k1\),小于它且与它互质的数的个数的和(即\(\sumφ\)),所以真正的答案就是
\[(\sum_k1=1^\lfloor \fracnd \rfloor φ(k1))*2-1\]
对\(φ\)求出前缀和\(sum\)
所以\[\Pi_i=1^n\Pi_j=1^ngcd(i,j)=\Pi_d=1^nd^sum(\lfloor \fracnd \rfloor)*2-1\]
好了,到现在复杂度为\(O(n+Tnlogn)\),可以拿到\(60\)分的好成绩(雾)
最后一个优化:
不难发现,\(\lfloor \fracnd \rfloor\)的取值只有\(2\sqrtn\)种,那么可以把\(\lfloor \fracnd \rfloor\)相等的所有\(d\)放在一起处理
假设某一段从\(i\)到\(j\)的所有数的这个值都等于\(x\),那么这一段的乘积就等于
\[\Pi_p=i^jp^sum(x)*2-1=i^sum(x)*2-1*(i+1)^sum(x)*2-1*...*j^sum(x)*2-1=(i*(i+1)*...*j)^sum(x)*2-1\]
那么先预处理出\(1-19260817\)的逆元\(inv(i)\),这一段的答案就是\((fac(j)*inv(fac(i-1)))^sum(x)*2-1\)
这样处理后的最终复杂度是\(O(n+T\sqrtnlog(n))\),可以愉快的通过此题
\(AC code\)(主要部分)
#define LL long long
const int mod=19260817;
LL ans;
LL quickpow(LL a,LL k)
if(!k)return 1;
LL res=quickpow(a,k>>1);
res=(res*res)%mod;
if(k&1)res=(res*a)%mod;
return res;
void pre()
phi[1]=1;
for(LL i=2;i<maxn;++i)
if(!notprime[i])prime[++cnt]=i,phi[i]=i-1;
for(LL j=1;j<=cnt&&prime[j]*i<maxn;++j)
notprime[prime[j]*i]=1;
if(i%prime[j])phi[prime[j]*i]=phi[i]*(prime[j]-1);
else
phi[prime[j]*i]=phi[i]*prime[j];
break;
for(int i=1;i<maxn;++i)phi[i]=phi[i-1]+phi[i];
fac[0]=1;
for(int i=1;i<maxn;++i)fac[i]=((LL)fac[i-1]*i)%mod;
inv[0]=inv[1]=1;
for(int i=2;i<mod;++i)inv[i]=(((-(LL)(mod/i)*(LL)(inv[mod%i]))%mod)+mod)%mod;
int T;
int main()
pre();
scanf("%d",&T);
while(T--)
scanf("%d",&n);
ans=quickpow(fac[n],2*n);
LL ans2=1;
for(LL i=1,L;i<=n;i=L+1)
LL p=2*phi[n/i]-1;
L=n/(n/i);
ans2=(ans2*quickpow((fac[L]*(LL)inv[fac[i-1]])%mod,p))%mod;
ans2=(ans2*ans2)%mod;
printf("%lld\n",(ans*(LL)inv[ans2])%mod);
以上是关于luogu P4917 天守阁的地板的主要内容,如果未能解决你的问题,请参考以下文章
(luogu题解搬运系列)luogu p2651 添加括号Ⅲ