博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 2301 莫比乌斯反演
阅读量:5294 次
发布时间:2019-06-14

本文共 1478 字,大约阅读时间需要 4 分钟。

 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。

这里题目意思很明显

对于要求的f[n] = sigma (a≤x≤b) sigma(c≤y≤d) [gcd(x,y)=k] =  sigma (1≤x≤b) sigma(1≤y≤d) [gcd(x,y)=k] + sigma (1≤x≤a-1) sigma(1≤y≤c-1) [gcd(x,y)=k] - sigma (1≤x≤a-1) sigma(1≤y≤d) [gcd(x,y)=k] -  sigma (1≤x≤b) sigma(1≤y≤c-1) [gcd(x,y)=k] 

对于每一个g[n] = sigma(1≤x≤a) sigma(1≤y≤c) [gcd(x,y)=k] = sigma(1≤x≤a/k) sigma(1≤y≤c/k) [gcd(x,y)=1] = sigma(1≤x≤a/k) sigma(1≤y≤c/k) sigma(d|gcd(x,y)) mu[d] = sigma(d) mu[d]*a/k/d*c/k/d

 

a/k/d*c/k/d 这一段区间相等的部分可以加在一起算,得到当前一样值的结束是 min(x/(x/i) , y/(y/i)) 

记录莫比乌斯函数的前缀和就可以整段区间更新,这样循环就缩小到了sqrt(n)的复杂度

1 #include 
2 using namespace std; 3 #define ll long long 4 #define N 50000 5 int mu[N+10] , prime[N+10] , tot , sum[N+10]; 6 bool check[N+10]; 7 8 void get_mu() 9 {10 mu[1] = 1;11 for(int i=2 ; i<=N ; i++){12 if(!check[i]){13 prime[tot++] = i;14 mu[i] = -1;15 }16 for(int j=0 ; j
N) break;18 check[i*prime[j]] = true;19 if(i%prime[j]){20 mu[i*prime[j]] = -mu[i];21 }else break;22 }23 }24 for(int i=1 ; i<=N ; i++) sum[i]=sum[i-1]+mu[i];25 }26 27 int a,b,c,d,k;28 29 int solve(int x , int y)30 {31 x/=k , y/=k;32 int mx = min(x , y) , len , ret=0;33 for(int i=1 ; i<=mx ; i=len+1)34 {35 // cout<
<<" "<
<

 

转载于:https://www.cnblogs.com/CSU3901130321/p/4784338.html

你可能感兴趣的文章
软件测试(基础理论一)摘
查看>>
consonant combination
查看>>
基于Flutter实现的仿开眼视频App
查看>>
析构器
查看>>
驱动的本质
查看>>
Swift的高级分享 - Swift中的逻辑控制器
查看>>
https通讯流程
查看>>
Swagger简单介绍
查看>>
C# 连接SQLServer数据库自动生成model类代码
查看>>
关于数据库分布式架构的一些想法。
查看>>
大白话讲解 BitSet
查看>>
sql语句中where与having的区别
查看>>
Python数据分析入门案例
查看>>
0x7fffffff的意思
查看>>
Java的值传递和引用传递
查看>>
HTML5的服务器EventSource(server-sent event)发送事件
查看>>
vue-devtools 获取到 vuex store 和 Vue 实例的?
查看>>
Linux 中【./】和【/】和【.】之间有什么区别?
查看>>
Ubuntu sudo 出现 is not in the sudoers file解决方案
查看>>
内存地址对齐
查看>>