zoukankan      html  css  js  c++  java
  • P1829 [国家集训队]Crash的数字表格 / JZPTAB

    推式子太快乐啦!虽然我好蠢而且dummy和maomao好巨(划掉)

    思路

    莫比乌斯反演的题目
    首先这题有(O(sqrt n))的做法但是我没写咕咕咕
    然后就是爆推一波式子

    [sum_{i=1}^{n}sum_{j=1}^{m}lcm(i,j) ]

    [sum_{i=1}^{n}sum_{j=1}^{m}frac{i imes j}{gcd(i,j)} ]

    设$ gcd(i,j)=d$

    [sum_{d=1}^{n}dsum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}i imes j imes[gcd(i,j)=1] ]

    [p_1=lfloorfrac{n}{d} floor\ p_2=lfloorfrac{m}{d} floor ]

    (f(x))为满足条件(1 le i le p_1)且$1 le j le p_2 (且)[gcd(i,j)=x](的)i imes j$的和

    则可以推出(F(x))

    [F(x)=sum_{x|d}f(d) ]

    所以(F(x))为满足条件(1 le i le p_1)且$1 le j le p_2 (且)[x|gcd(i,j)](的)i imes j$的和

    所以

    [F(x)=x^2 imes sum_{i=1}^{lfloorfrac{p_1}{x} floor}i imes sum_{j=1}^{lfloorfrac{p_2}{x} floor}j ]

    因为

    [f(x)=sum_{x|d}mu(frac{d}{x})F(d) ]

    所以

    [f(x)=sum_{x|d}mu(frac{d}{x}) imes d^2 imes sum_{i=1}^{lfloorfrac{p_1}{d} floor}i imes sum_{j=1}^{lfloorfrac{p_2}{d} floor}j ]

    所以

    [f(x)=sum_{t=1}mu(t) imes (tx)^2 imes sum_{i=1}^{lfloorfrac{p_1}{tx} floor}i imes sum_{j=1}^{lfloorfrac{p_2}{tx} floor}j ]

    [ans=sum_{d=1}^{n}dsum_{t=1}^{lfloorfrac{n}{d} floor}mu(t) imes (t)^2 imes sum_{i=1}^{lfloorfrac{n}{td} floor}i imes sum_{j=1}^{lfloorfrac{m}{td} floor}j ]

    然后两个整除分块搞定,复杂度(O(n))

    然后dummy教了我一种新的计算方式

    [sum_{d=1}^{n}dsum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}i imes j imes[gcd(i,j)=1] ]

    发现[gcd(i,j)=1]的形式有点眼熟
    直接把(mu)带进去算

    [sum_{d=1}^{n}dsum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=1}^{lfloorfrac{m}{d} floor}i imes j imes sum_{p|gcd(i,j)}mu(p) ]

    算得

    [sum_{d=1}^ndsum_{p=1}^{lfloorfrac{n}{d} floor}p^2mu(p)sum_{i=1}^{lfloorfrac{n}{dp} floor}isum_{j=1}^{lfloorfrac{n}{dp} floor}j ]

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int INV = 10050505;
    const int MOD = 20101009;
    int isprime[10010000],iprime[10010000],cnt,mu[10010000],summu[10010000],n,m;
    void prime(int n){
        isprime[n]=true;
        mu[1]=1;
        for(int i=2;i<=n;i++){
            if(!isprime[i])
                iprime[++cnt]=i,mu[i]=-1;
            for(int j=1;j<=cnt&&iprime[j]*i<=n;j++){
                isprime[iprime[j]*i]=true;
                mu[iprime[j]*i]=-mu[i];
                if(i%iprime[j]==0){
                    mu[iprime[j]*i]=0;
                    break;
                }
            }
        }
        for(int i=1;i<=n;i++)
            summu[i]=(summu[i-1]%MOD+1LL*(mu[i]%MOD+MOD)%MOD*i%MOD*i%MOD)%MOD;
    }
    long long calc2(int n,int m){
        long long ans=0;
        for(int l=1,r;l<=min(n,m);l=r+1){
            r=min(n/(n/l),m/(m/l));
            ans=(ans%MOD+1LL*(summu[r]-summu[l-1]%MOD+MOD)%MOD*(1+n/l)%MOD*(n/l)%MOD*INV%MOD*(1+m/l)%MOD*(m/l)%MOD*INV%MOD)%MOD;
        }
        return ans;
    }
    long long calc1(int n,int m){
        long long ans=0;
        for(int l=1,r;l<=min(n,m);l=r+1){
            r=min(n/(n/l),m/(m/l));
            ans=(ans%MOD+1LL*(r-l+1)%MOD*(r+l)%MOD*INV%MOD*calc2(n/l,m/l)%MOD)%MOD;
        }
        return ans;
    }
    int main(){
        prime(10001000);
        scanf("%d %d",&n,&m);
        if(n<m)
            swap(n,m);
        long long ans=calc1(n,m);
        printf("%lld",ans);
    }
    
  • 相关阅读:
    java字符串常用操作(查找、截取、分割)
    java StringBuffer的length()和capacity()方法比较
    java四种权限修饰符
    HDU-Tick and Tick
    HDU
    Piggy-Bank (完全背包)
    HDU
    1008 Elevator (20 分)(模拟)
    最少拦截系统 (动态规划)
    外星人的语言(进制转换)
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10073395.html
Copyright © 2011-2022 走看看