zoukankan      html  css  js  c++  java
  • [NOI2010]能量采集

    Description:

    求$ sum_{i=1}^n sum_{j=1}^m gcd(i,j)*2-1$

    Hint:

    (n,m<=10^5​)

    Solution:

    $ Ans=2*sum_{i=1}^n sum_{j=1}^m gcd(i,j) -n*m $

    $sum_{i=1}^n sum_{j=1}^m gcd(i,j)=sum_{T=1}nsum_{d=1}{T } mu(frac{T}{d}) *d *lfloor frac{n}{T} floor lfloor frac{m}{T} floor $

    $ =sum_{T=1}^n phi (T) *lfloor frac{n}{T} floor lfloor frac{m}{T} floor $

    线性筛即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mxn=1e5+5;
    int tot,phi[mxn],p[mxn],vis[mxn];
    ll sum[mxn];
    
    void sieve(int n)
    {
        phi[1]=1;
        for(int i=2;i<=n;++i) {
            if(!vis[i]) phi[i]=i-1,p[++tot]=i;
            for(int j=1;j<=tot&&p[j]*i<=n;++j) {
                vis[p[j]*i]=1;
                if(i%p[j]) phi[p[j]*i]=phi[i]*(p[j]-1);
                else {
                    phi[p[j]*i]=phi[i]*p[j];
                    break ;
                }
            }
        }
        for(int i=1;i<=n;++i) sum[i]=sum[i-1]+phi[i];
    } 
    
    int main()
    {
        int n,m; scanf("%d%d",&n,&m); 
        if(n>m) swap(n,m); ll ans=0; sieve(100000);
        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);
        }
        printf("%lld",ans-1ll*n*m+ans); //n*m可能会炸,开long long
    }
    
  • 相关阅读:
    2018年12月29日 Oracle查询性能优化
    B
    A
    洛谷 P2447 [SDOI2010]外星千足虫
    洛谷 P5358 [SDOI2019]快速查询
    欠的题目
    ZJU-ICPC Summer 2020 Contest 8 B-Picnic
    洛谷 P3164 [CQOI2014]和谐矩阵
    K
    J
  • 原文地址:https://www.cnblogs.com/list1/p/10391082.html
Copyright © 2011-2022 走看看