zoukankan      html  css  js  c++  java
  • hdu6134 Battlestation Operational 莫比乌斯第一种形式

    /**
    题目:hdu6134 Battlestation Operational
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6134
    题意:f(n) = sigma[1<=i<=n]sigma[1<=j<=i]ceil[i/j] (gcd(i,j)==1)
    给定一个n,求f(n);
    思路:
    公式: n = sigma[d|n]phi[d] = sigma[d|n]phi[n/d]; phi[x]表示<=x的数与x互质的个数。
    证明: gcd(i,n)==d => gcd(i/d,n/d)=1; 那么和n最大公约数为d的个数为phi[n/d]; 所以n = sigma[d|n]phi[n/d] = sigma[d|n]phi[d];
    
    根据n = sigma[d|n]phi[d];
    那么有定义:
    h(i)表示sigma[1<=j<=i]ceil[i/j] (gcd(i,j)==1)  这里的j都是和i互质时候计算的结果。
    g(i)表示sigma[1<=j<=i]ceil[i/j]
    
    那么h(i) = sigma[d|i]mu[d]*g(i/d);
    
    计算所有的g(d)(1<=d<=n)通过枚举j跳在d中跳的方式处理出来,然后前缀和(也可以直接计算出来。不需要再求前缀和,具体看代码)
    
    计算出来所有的h(i)。f(i) = sigma[1<=j<=i]h(j);
    
    */
    
    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N = 1e6+10;
    const int mod = 1e9 + 7;
    LL f[N], g[N], h[N];
    int prime[N], tot, not_prime[N];
    int mu[N];
    void mobius()
    {
        mu[1] = 1;
        tot = 0;
        for(int i = 2; i < N; i++){
            if(!not_prime[i]){
                prime[++tot] = i;
                mu[i] = -1;
            }
            for(int j = 1; prime[j]*i<N; j++){
                not_prime[prime[j]*i] = 1;
                if(i%prime[j]==0){
                    mu[prime[j]*i] = 0;
                    break;
                }
                mu[prime[j]*i] = -mu[i];
            }
        }
    }
    void init()
    {
        for(int i = 1; i < N; i++){
            g[i]++;
            for(int j = i+1; j < N; j+=i){
                g[j]++;
            }
        }
        for(int i = 1; i < N; i++) g[i] = (g[i]+g[i-1])%mod;
    
        for(int i = 1; i < N; i++){
            for(int j = i; j < N; j+=i){
                h[j] = (h[j]+mu[i]*g[j/i]%mod+mod)%mod;
            }
        }
        for(int i = 1; i < N; i++){
            f[i] = (f[i-1]+h[i])%mod;
        }
    }
    int main()
    {
        int n;
        mobius();
        init();
        while(scanf("%d",&n)==1)
        {
            printf("%lld
    ",f[n]);
        }
        return 0;
    }
  • 相关阅读:
    listview 加载性能优化 viewholder
    eclipse使用有感
    android常见的错误
    填充父窗体布局问题
    setTag()/getTag()
    自己动手实现自旋锁
    新手学信息检索6:谈谈二值独立模型
    自己动手编译、运行Java程序
    新手学信息检索5:正确率召回率与搜索引擎的评价
    新手学信息检索4:向量空间模型与相似度计算
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7384098.html
Copyright © 2011-2022 走看看