码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P4917 天守阁的地板

时间:2019-07-23 00:07:05      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:https   isp   一起   预处理   规格   prime   a*   quic   处理   

题目描述:

链接

\(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)\)(木板不允许旋转),所以需要最小的木板数量是\(\frac{lcm(a,b)}{a}*\frac{lcm(a,b)}{b}\)

问题中说要把所有可能的\((a,b)\)的答案求乘积,那么问题就转换成了求\[\Pi_{i=1}^{n}\Pi_{j=1}^{n}\frac{lcm(i,j)^2}{i*j}\]

首先你必须知道

\[lcm(i,j)*gcd(i,j)=i*j\](唯一分解后易证)

因此
\[\Pi_{i=1}^{n}\Pi_{j=1}^{n}\frac{lcm(i,j)^2}{i*j}=\Pi_{i=1}^{n}\Pi_{j=1}^{n}\frac{i*j}{gcd(i,j)^2}\]

先考虑分子:
\[\Pi_{i=1}^{n}\Pi_{j=1}^{n}i*j=(1^{2n}*2^{2n}*...*n^{2n})=(n!)^{2n}\]

所以可以先\(O(n)\)预处理出阶乘\(fac(i)\),用快速幂\(O(logn)\)算出分子

接下来考虑分母

为了方便,可以先求出\[\Pi_{i=1}^{n}\Pi_{j=1}^{n}gcd(i,j)\]
再平方

考虑枚举\(d\),那么我们求出对于每个\(d\)有多少对\((i,j)\)满足\(gcd(i,j)=d\)再套用快速幂即可

显然,\(i,j\)都是\(d\)的倍数是必要条件,所以设\(i=k_1d,j=k_2d(k1,k2≤\lfloor \frac{n}{d} \rfloor)\)
那么当且仅当\(gcd(k1,k2)=1\)\(k1,k2\)互质时符合\(gcd(i,j)=d\)的条件(否则\(gcd\)可以扩大为\(d*gcd(k1,k2)\))
不妨令 \(k1>k2\),那么符合条件的点对数 为每个在范围内的\(k1\),小于它且与它互质的数的个数的和(即\(\sumφ\)),所以真正的答案就是
\[(\sum_{k1=1}^{\lfloor \frac{n}{d} \rfloor} φ(k1))*2-1\]

\(φ\)求出前缀和\(sum\)

所以\[\Pi_{i=1}^{n}\Pi_{j=1}^{n}gcd(i,j)=\Pi_{d=1}^{n}d^{sum(\lfloor \frac{n}{d} \rfloor)*2-1}\]

好了,到现在复杂度为\(O(n+Tnlogn)\),可以拿到\(60\)分的好成绩(雾)

最后一个优化:
不难发现,\(\lfloor \frac{n}{d} \rfloor\)的取值只有\(2\sqrt{n}\)种,那么可以把\(\lfloor \frac{n}{d} \rfloor\)相等的所有\(d\)放在一起处理

假设某一段从\(i\)\(j\)的所有数的这个值都等于\(x\),那么这一段的乘积就等于
\[\Pi_{p=i}^{j}p^{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\sqrt{n}log(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 天守阁的地板

标签:https   isp   一起   预处理   规格   prime   a*   quic   处理   

原文地址:https://www.cnblogs.com/study-ysj/p/tianshouge.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!