• [bzoj] 2693 jzptab || 莫比乌斯反演


    原题

    (sum^{n}_{x=1}sum^{m}_{y=1}lcm(x,y))


    (sum^{n}_{x=1}sum^{m}_{y=1}lcm(x,y))

    (=sum_{p}sum^{lfloor frac{n}{p} floor}_{x=1}sum^{lfloor frac{m}{p} floor}_{y=1}i*j*p[gcd(x,y)==1])

    (=sum_{p}sum^{lfloor frac{n}{p} floor}_{x=1}sum^{lfloor frac{m}{p} floor}_{y=1}sum_{d|gcd(x,y)}mu(d)*x*y*p)

    (=sum_{p}p*sum_dsum^{lfloor frac{n}{p} floor}_{d|x}sum^{lfloor frac{m}{p} floor}_{d|y}sum_{d|gcd(x,y)}mu(d)*x*y)

    (=sum_{p}p*sum_dmu(d)*d^2*sum^{lfloor frac{n}{p} floor}_{d|x}sum^{lfloor frac{m}{p} floor}_{d|y}frac{x}{d}*frac{y}{d})

    设i=x/d,j=y/d

    原式(=sum_{p}p*sum_dmu(d)*d^2*sum^{lfloor frac{n}{pd} floor}_{i=1}sum^{lfloor frac{m}{pd} floor}_{j=1}i*j)

    因为i,j是连续的,所以为等差数列求和:

    (sum(i,j)=sum^{lfloor frac{n}{pd} floor}_{i=1}sum^{lfloor frac{m}{pd} floor}_{j=1}i*j=((lfloor frac{n}{pd} floor)*(lfloor frac{n}{pd} floor+1)/2)*((lfloor frac{m}{pd} floor)*(lfloor frac{m}{pd} floor+1)/2))

    (=sum_{p}p*sum_dmu(d)*d^2*sum(lfloor frac{n}{pd} floor,lfloor frac{m}{pd} floor))

    对于(sum_{p}p*sum_dmu(d)*d^2)这一部分可以预处理出前缀和,(sum(lfloor frac{n}{pd} floor,lfloor frac{m}{pd} floor))可以(O(sqrt(n))枚举。

    #include<cstdio>
    #include<algorithm>
    #define N 10000010
    #define mod 100000009ll
    typedef long long ll;
    using namespace std;
    ll pri[N>>3],tot,g[N],sum[N],t,n,m,ans;
    bool vis[N];
    
    void init()
    {
        g[1]=sum[1]=1;
        for (ll i=2;i<N;i++)
        {
    	if (!vis[i])
    	{
    	    pri[++tot]=i;
    	    g[i]=((-(ll)(i-1)*i)%mod+mod)%mod;
    	}
    	for (ll j=1;j<=tot && pri[j]*i<N;j++)
    	{
    	    vis[i*pri[j]]=1;
    	    if (i%pri[j]==0)
    	    {
    		g[i*pri[j]]=g[i]*pri[j]%mod;
    		break;
    	    }
    	    g[i*pri[j]]=g[i]*g[pri[j]]%mod;
    	}
    	sum[i]=sum[i-1]+g[i];
        }
    }
    
    ll F(ll x,ll y)
    {
        return ((ll)(x+1)*x/2)%mod*(((ll)(y+1)*y/2)%mod)%mod;
    }
    
    int main()
    {
        init();
        scanf("%lld",&t);
        while (t--)
        {
    	scanf("%lld%lld",&n,&m);
    	if (n>m) swap(n,m);
    	ans=0;
    	for (int i=1,last=0;i<=n;i=last+1)
    	{
    	    last=min(n/(n/i),m/(m/i));
    	    ans+=F(n/i,m/i)*(sum[last]-sum[i-1]+mod)%mod;
    	    ans%=mod;
    	}
    	printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Odoo13_多选下拉框
    Odoo13_联动下拉框
    Odoo13_上传文件并指定保存到位置
    Flask_cookie和session
    云原生设计理念
    docker 清理掉none对象,未使用网络,缓存等命令
    解决ssh连接中断问题
    python更改程序运行目录为程序所在文件夹
    Vuejs Cron 表达式校验
    Kubernetes WebSocket: Error during WebSocket handshake: Unexpected response code: 403
  • 原文地址:https://www.cnblogs.com/mrha/p/8205338.html
Copyright © 2020-2023  润新知