HDU 6134 Battlestation Operational(莫比乌斯反演)

 

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6134

 

【题目大意】

  求ni=1ij=1ij[(i,j)==1]

 

【题解】

  设 g(i)=ni=1ij=1ijh(i)=ni=1ij=1ij[(i,j)==1]

  有 g(i)=d|iidj=1idj[(i,jd)==d]

  =d|iidj=1idj[(id,j)==1]

  =d|ih(id)

  =d|ih(d)

  所以有h(i)=d|iμ(d)g(id)

  考虑如何计算 g(i)

  我们发现i对于i贡献为1i+12i贡献为22i+13i贡献为3……

  贡献为区间更新,因此我们可以用差分数列统计,计算出g(i)之后,反演计算h(i)即可。

 

【代码】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1000010;
typedef long long LL;
const LL P=1000000007LL;
int tot,p[N],miu[N],v[N];
void Mobius(int n){
    int i,j;
    for(miu[1]=1,i=2;i<=n;i++){
        if(!v[i])p[tot++]=i,miu[i]=-1;
        for(j=0;j<tot&&i*p[j]<=n;j++){
            v[i*p[j]]=1;
            if(i%p[j])miu[i*p[j]]=-miu[i];else break;
        }
    }
}  
LL sum[N],ans[N];
void AddMod(LL &a,LL b){a+=b;if(a>=P)a-=P;if(a<0)a+=P;}
void Init(int n){
    for(int j=1;j<=n;j++){ans[j]++;for(int i=j;i<=n;i+=j)ans[i+1]++;}
    for(int i=1;i<=n;i++)AddMod(ans[i],ans[i-1]);
    for(int j=1;j<=n;j++){if(miu[j])for(int i=j;i<=n;i+=j)AddMod(sum[i],miu[j]*ans[i/j]);}
    for(int i=1;i<=n;i++)AddMod(sum[i],sum[i-1]);
}
int n;
int main(){
    Mobius(1000000);
    Init(1000000);
    while(~scanf("%d",&n))printf("%d\n",sum[n]);
    return 0;
}
posted @   forever97  阅读(453)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
历史上的今天:
2014-08-18 HDU 4957 Poor Mitsui
点击右上角即可分享
微信分享提示