BZOJ 2301 莫比乌斯反演入门

2301: [HAOI2011]Problem b

Description

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

Input

第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k

Output

共n行,每行一个整数表示满足要求的数对(x,y)的个数

Sample Input

2

2 5 1 5 1

1 5 1 5 2

Sample Output

14

3
此题作为我的莫比乌斯反演的入门题

推荐文章

    https://wenku.baidu.com/view/fbec9c63ba1aa8114431d9ac.html      学习莫比乌斯反演

    https://wenku.baidu.com/view/fbe263d384254b35eefd34eb.html
       http://blog.csdn.net/outer_form/article/details/50590197

简单的说下莫比乌斯反演的作用

  对于一个函数f(n) 我们很难直接求出它的值,但是我可以求出倍数和或者约束和F(n),那么我们就可以将F通过莫比乌斯反演来得到f,基于容斥思想

  莫比乌斯反演常用于处理一些gcd的问题

代码如下:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long long LL;
const int maxn = 5e4+5000;
int p[maxn],mo[maxn],phi[maxn],cnt,sum[maxn];
int a,b,c,d,k;
bool vis[maxn];
void init()
{
    mo[1]=1;
    phi[1]=1;
    for(int i=2;i<=maxn-10;i++){
        if(!vis[i]){
            mo[i]=-1;
            phi[i]=i-1;
            p[cnt++]=i;
        }
        for(int j=0;j<cnt&&(ll)i*p[j]<=maxn-10;j++){
            vis[i*p[j]]=true;
            if(i%p[j]==0){
                mo[i*p[j]]=0;
                phi[i*p[j]]=phi[i]*p[j];
                break;
            }
            mo[i*p[j]]=-mo[i];
            phi[i*p[j]]=phi[i]*(p[j]-1);
        }
    }
}
ll solve (int n,int m)
{
    ll ret =  0;
    if (n>m) swap(n,m);
    for (int i=1,la=0;i<=n;i=la+1){
        la = min(n/(n/i),m/(m/i));
        ret+=(long long)(sum[la]-sum[i-1])*(n/i)*(m/i);
    }
    return ret;
}
int main()
{
    //freopen("de.txt","r",stdin);
    init();
    int T;
    for (int i=1;i<=50000;++i) sum[i] = sum[i-1] + mo[i];
    scanf("%d",&T);
    while (T--){
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        ll ans = solve(b/k,d/k)-solve((a-1)/k,d/k)-solve((c-1)/k,b/k)+solve((a-1)/k,(c-1)/k);
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-11-08 11:17:14

BZOJ 2301 莫比乌斯反演入门的相关文章

bzoj 2301 莫比乌斯反演

求$(i,j)=k$的一系列模板题之一. 但是这里i,j是有下界的,注意用容斥去掉重复组,其他都一样了. /** @Date : 2017-09-09 19:21:18 * @FileName: bzoj 2301 莫比乌斯反演 多组 范围内 GCD=k.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : $Id$ */ #inclu

[知识点]莫比乌斯反演入门

因为今天有较为充足的时间,于是果断入坑反演OvO 直接上公式和概念: 定理:和是定义在非负整数集合上的两个函数,并且满足条件,那么我们得到结论 在上面的公式中有一个函数,称其为莫比乌斯函数 它的定义如下: (1)若,那么 (2)若,均为互异素数,那么 (3)其它情况下 对于函数,它有如下的常见性质: (1)对任意正整数有 (2)对任意正整数有 (3)为积性函数 数论上积性函数的定义:     积性函数的性质: ①  ②积性函数的前缀和也是积性函数 由此可以线性求出莫比乌斯函数: mu[1]=1;

莫比乌斯反演入门

Preface 莫比乌斯反演,数论中最令人头疼的一部分.可以把一些十分困难的问题变得依然很困难简单. 很早之前就想好好学一下反演,但苦于连\(\mu\)的意义都搞不懂.直到有一天我偶然看到了一句话: 那些各种各样的性质与定理,大多是前人几年甚至几十年才得出来的,哪里是你几天就能理解并证明的. (PS:每当你阅读本文并感到无法理解时,请再次阅读一遍上面的话.) 因此我就开始一脸懵逼地强行学习起反演了,一段时间之后发现也没有那么难理解. 学习的过程大多参照peng-ym's blog 关于莫比乌斯函

莫比乌斯反演入门解析

以下教程前半部分来自B站电子科技大学的视频 https://www.bilibili.com/video/av43470417?from=search&seid=9275043167445755699.菜鸡如我就还没看懂. 分割线后半部分教程来自 https://www.luogu.org/blog/An-Amazing-Blog/mu-bi-wu-si-fan-yan-ji-ge-ji-miao-di-dong-xi . 教程一 问题引入 给定整数 N 和 M .求满足 \(1 \leq x

bzoj 2154 莫比乌斯反演求lcm的和

题目大意: 表格中每一个位置(i,j)填的值是lcm(i,j) , 求n*m的表格值有多大 论文贾志鹏线性筛中过程讲的很好 最后的逆元我利用的是欧拉定理求解的 我这个最后线性扫了一遍,勉强过了,效率不是很高... 1 /*bzoj 2154*/ 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 #define ll long long 6 #define N 10000000 7 const int MOD = 20101009; 8

bzoj 1101 莫比乌斯反演

最裸的莫比乌斯 #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e5 + 7; const int M = 1e6 + 7; const int inf = 0x3f3f3f3f; const LL INF

BZOJ 3561 莫比乌斯反演

$\Sigma_{i=1}^n\Sigma_{j=1}^mlcm(i,j)^{gcd(i,j)}$ $=\Sigma_{i=1}^n\Sigma_{j=1}^m (\frac{i*j}{gcd(i,j)})^{gcd(i,j)}$ 枚举gcd(i,j)=d $=\Sigma_{d=1}^n\Sigma_{i=1}^{\lfloor \frac{n}{d}\rfloor}\Sigma_{j=1}^{\lfloor \frac{m}{d}\rfloor}(d*i*j)^d*(gcd(i,j)==1)

BZOJ 2820 莫比乌斯反演

思路: $\Sigma_{i=1}^n\Sigma_{j=1}^mgcd(i,j)==p(p是素数)$ $\Sigma_{p是素数}^{p<=n}\Sigma_{i=1}^{\lfloor \frac{n}{p} \rfloor}\Sigma_{j=1}^{\lfloor \frac{m}{p} \rfloor}gcd(i,j)==1$ 由$e=μ|1$可得$gcd(i,j)==1 等价于 \Sigma_{d|gcd(i,j)} μ(d)$ 所以原式为 $\Sigma_{p是素数}^{p<=n

HYSBZ - 2301 莫比乌斯反演

链接 题解:直接用公式算,用容斥来减掉重复计算的部分 但是我犯了一个非常sb的错误,直接把abcd除k了,这样算a-1的时候就错了,然后举的例子刚好还没问题= = ,结果wa了好几发 //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3