zoukankan      html  css  js  c++  java
  • bzoj2005 能量采集 gcd 容斥

    ans = sigma_x(sigma_y(gcd(x,y) * 2 - 1)),1<=x<=n,1<=y<=m

    枚举x,y,O(nmlogn),超时

    换个角度,枚举d = gcd(x,y)

    d对ans的贡献为2*d-1

    若有n个(x,y)使得gcd(x,y) = d,则贡献为n * (2 * d - 1)

    f(d) 表示gcd(x,y) = d 的(x,y)个数

    ans = sigma(f[d] * (2 * d - 1)),1 <= d <= min(n,m)

    那么问题就是求f(d)

    g(d) 表示d|gcd(x,y)的(x,y)个数

    则g(d) = (n / d) * (m / d)

    f(d) = g(d) - f(i * d) , 2 <= i <= min(n,m) / d

    反序遍历d,即min(n,m) 到 1

    求f(d),累加f(d) * (2 * d - 1) 到ans

    O(nlogn)

                                                
      //File Name: bzoj2005.cpp
      //Author: long
      //Mail: 736726758@qq.com
      //Created Time: 2016年02月12日 星期五 14时08分18秒
                                       
    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    
    #define LL long long
    
    using namespace std;
    
    const int MAXN = 100000+5;
    
    LL f[MAXN];
    
    void solve(int n,int m)
    {
        LL ans = 0LL;
        int mi = min(n,m);
        memset(f,0,sizeof f);
        for(int i=mi;i>0;i--){
            f[i] = (LL)(n/i) * (m/i);
            for(int j=2;j<=mi/i;j++){
                f[i] -= f[j*i];
            }
            ans += f[i] * (i * 2LL - 1);
        }
    
        cout << ans << endl;
        return ;
    }
    
    int main()
    {
        int n,m;
        while(~scanf("%d %d",&n,&m)){
            solve(n,m);
        }
        return 0;
    }
  • 相关阅读:
    RxJava+okhttp3
    RetrofitOkHttp网络请求
    布局111
    网络请求展示数据
    一级列表展示购物车
    终极MVP二级购物车
    将博客搬至CSDN
    nyoj-开灯问题
    nyoj-数乌龟
    nyoj 正三角形的外接圆面积
  • 原文地址:https://www.cnblogs.com/-maybe/p/5556960.html
Copyright © 2011-2022 走看看