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\n",f[n]);
    }
    return 0;
}
时间: 2024-12-07 09:54:50

hdu6134 Battlestation Operational 莫比乌斯第一种形式的相关文章

【莫比乌斯反演】【线性筛】hdu6134 Battlestation Operational

看这个题解吧:http://blog.csdn.net/wubaizhe/article/details/77338332 代码里顺便把几个常用的线性筛附上了. #include<cstdio> #include<algorithm> using namespace std; #define MOD 1000000007 #define N 1000000 bool notpri[N+5]; int pri[N+5],n,mu[N+5],sum[N+5]; typedef long

2017多校第8场 HDU 6134 Battlestation Operational 莫比乌斯反演

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6134 题意: 解法: 那么g(n)怎么求,我们尝试打表发现g(n)是有规律的,g(n)=g(n-1)+d(n-1)+1,其中d(i)表示i的因子个数,这个我们是可以通过线性筛O(n)处理出来的,之后再O(n)维护g(i)的前缀和,就可以在单组sqrt(n)的复杂度下得到答案了. #include <bits/stdc++.h> using namespace std; typedef long l

后台布局的第一种形式

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .pg-header{ height: 48px; background-color: #1d9ad6; color: white; } .pg-content{} .pg-footer{} .pg-c

Core CLR 自定义的Host官方推荐的一种形式(第一种)

.Net Core CLR提供两种Host API访问 托管代码的形式,按照微软官方的说法,一种是通过CoreClr.DLL来直接调用托管生成的DLL程序集,另外一种是通过CoreClr里面的C导出函数GetCLRRuntimeHost获取到IID_ICLRRuntimeHost4然后访问托管代码. 其实这两种形式可以合二为一,第一种更简单,更方便的控制托管代码.第二种更灵活些,在一些老旧的主机上会用到这些代码,实际上第一种形式是扩充了第二种访问形式,进行了一个整体封装,原理上其实还是一样的.

事件绑定的第二种形式 &amp; call

<script> //call 函数下的一个方法,call方法第一个参数可以改变函数执行过程中的内部this的指向,call方法第二个参数开始就是原来函数的参数列表. function fn1(a, b) { alert(this); alert(a + b); } fn1(); //window fn1.call(null, 10, 20); //调用函数 fn1() == fn1.call() </script> <script> //给一个对象绑定一个事件处理函数

事件绑定的第二种形式

一.过去,给一个对象绑定一个事件,来处理函数的形式,如obj.onclick=fn1,我们称之为事件绑定的第一种形式(赋值形式). 这种形式的有一种缺点就是:同一个对象的同一个事件不能同时处理两个不同的函数. 例如: function fn1(){ alert("A") } function fn2(){ alert("B") } document.onclick=fn1; document.onclick=fn2;//后面一个事件会覆盖前面一个事件 二.为了解决上

【REACT NATIVE 系列教程之一】触摸事件的两种形式与四种TOUCHABLE组件详解

本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/react-native/2203.html 本文是RN(React Native)系列教程第一篇,当然也要给自己的群做个广告:   React Native @Himi :126100395  刚创建的群,欢迎一起学习.讨论.进步. 本文主要讲解两点: 1.   PanResponder:触摸事件,用以获取用户手指所在屏幕的坐标(x,y)或触

javascript——事件绑定第二种形式

 事件绑定第一种形式:obj.onclick = fn1; 给文档添加多个点击事件,后面会覆盖前面的事件,所以只有最后一个事件执行了. window.onload = function(){ function fn1(){alert('1');} function fn2(){alert('2');} function fn3(){alert('3');} document.onclick = fn1; document.onclick = fn2; document.onclick = fn3

信息共享的另一种形式--复用

共享的第一种形式是在不同人.不同部门.不同单位之间共享,这是大家经常理解的一种.而另一种共享形式大家可能不很注意,就是数据的纵向共享,历史数据的使用也是一种共享.如果说前面的共享理解为广度的共享,那么后一种是深度共享. 一次和搞工程设计专业的人聊天,说起原来非计算机画图时代,很辛苦,效率很低,而现在开始计算机画图了,效率提高了,有些图可以拿以前的图进行修改,我想这就是后一种共享,系统设计上有一个重要的概念是"复用". 也聊到写作方式,原来用纸笔,修改一稿非常费力,现在就简单了.