BZOJ3309 DZY Loves Math

BZOJ3309 DZY Loves Math

参考自这位大佬的推导思路以及这位大佬的实现思路

题目简述

定义\(f(n)\)\(n\)所含质因子的最大幂指数,如\(f(18)=f(2*3^2)=2\)
输入T组数据,求\(\sum_{i=1}^{n} \sum_{j=1}^{m} f(gcd(i,j))\)的值
\(T<=10000,1<=a,b<=10^7\)

公式推导(略)

\[\sum_{i=1}^{n} \sum_{j=1}^{m} f(gcd(i,j))\]
\[=\sum_{T=1}^{min(n,m)} \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor \sum_{d|T} f(d) \mu(\frac Td)\]

  • \(g(T)=\sum_{d|T}f(d) \mu(\frac Td)\)
    则现在的目标是在线性时间内求出\(g(x)\)的值
    \(T=p_1^{a_1}p_2^{a_2}…p_k^{a_k}\)\(d=p_1^{b_1}p_2^{b_2}…p_k^{b_k}\)\(c_i=a_i-b_i\)
    \(\frac Td=p_1^{c_1}p_2^{c_2}…p_k^{c_k}\)
    要使\(\mu(\frac Td) \neq0\),则\(c_1,c_2,…,c_k \leq1\)

分类讨论\(g(T)\)的值

  1. \(a_1,a_2,…,a_k\)并不全都相等
    此时设\(a_x\)最大,对于所有包含\(p_x^{a_x}\)\(d\)均有\(f(d)=a_x\)
    对于这些\(d\)\(p_i(i \neq x)\)的指数的选择均有两个,为\(a_i-1,a_i\),则一共能组合出\(2^{k-1}\)个不同的\(d\)
    设其中\(d_1,d_2\)的质因子中除\(p_y\)一项之外的指数均相等,则\(\mu(d_1)=-\mu(d_2)\)
    而这样\(\mu\)值相反的\(d\)共有\(2^{k-2}\)组,各自相加后的和就为0即
    \[[\sum_{d|T,p_x^{a_x} |d} f(d) \mu(\frac Td) ]=0\]
    之后对于剩下取\(p_x^{a_x-1}\)\(d\) 执行同样的分析,发现所有以\(a_q\)为最大值的的\(d\)的和均为0,所以此时\(g(T)=0\)

  2. \(A=a_1=a_2=…=a_k\)\(a_1,a_2,…,a_k\)均相等
    此时\(f(d)=\begin {cases} A(b_1,b_2,…,b_k中至少有一个值为A)\\ A-1(b_1=b_2=…=b_k=A-1) \end {cases}\)
    假设\(b_1=b_2=…=b_k=A-1\)的时\(d\)\(f(d)\)也为A
    \(g(T)\)类似于上一种情况的推导,其的和也为0
    当然,最后\(g(T)\)要减去某特殊\(d\)多加的\(1*\mu(\frac Td)\)
    所以此情况下\(g(T)=-(-1)^{k}=(-1)^{k+1}\)

而线性求g(T),则需要记录每个点的最小质因子及个数,除去该最小质因子后的值
这里就感性理解一下吧OvO

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 10000010
using namespace std;
int n,prim[N],pcnt,at[N],la[N],cnt[N];//at[i]记录i的最小质因子,la[i]=记录i除以所有at[i]后的值,cnt[i]记录at[i]的数量 
long long sum[N],g[N],f[N];
void eular()
{
    g[1]=0;
    for(int i=2;i<=N-10;i++)
    {
        if(!at[i])
        {
            prim[++pcnt]=i;
            at[i]=pcnt;
            g[i]=la[i]=cnt[i]=1;
        }
        for(int j=1;j<=at[i];j++)
        {
            if((long long)i*prim[j]>N-10)break;
            at[i*prim[j]]=j;
            if(j==at[i])//prim[j]为i的最小质因子,即也为prim[j]*i的最小质因子 
            {
                la[i*prim[j]]=la[i];
                cnt[i*prim[j]]=cnt[i]+1;
                if(la[i]==1)g[i*prim[j]]=1;
                else g[i*prim[j]]=(cnt[i]+1==cnt[la[i]]?-g[la[i]]:0);
            }
            else//prim[j]为新出现的质因子,个数为1 
            {
                la[i*prim[j]]=i;
                cnt[i*prim[j]]=1;
                g[i*prim[j]]=(cnt[i]==1?-g[i]:0);
            }
        }
        sum[i]=sum[i-1]+g[i];
    }
}
long long mb(int n,int m)
{
    long long ans=0;
    if(n>m)swap(n,m);
    for(int l=1,r;l<=n;l=r+1)
    {
        r=min(n/(n/l),m/(m/l));
        ans+=(sum[r]-sum[l-1])*(n/l)*(m/l);
    }
    return ans;
}
int main(){
    eular();
    int a,b,T;
    cin>>T;
    while(T--)
    {
        scanf("%d%d",&a,&b);
        printf("%lld\n",mb(a,b));   
    }
    return 0;
} 

\(\color{white}{神秘数字:4372wyx}\)

转载于:https://www.cnblogs.com/jungezi/p/10332097.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值