[HDU1695]GCD + [HAOI2011]Problem b + [POI2007]ZAP-Queries【莫比乌斯反演】

[HDU1695]GCD

[HAOI2011]Problem b

[POI2007]ZAP-Queries

令\[ans(n, m)=\sum_{i=1}^n\sum_{j=1}^m[GCD(i, j) == k]\]

\[=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[GCD(i, j) == 1]\]

令\[f(d)=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[GCD(i, j) == d]\]

\[g(x)=\sum_{x|d}f(d)\]

\[=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[x|GCD(i, j)]\]

\[=\sum_{i=1}^{\lfloor\frac{n}{xk}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{xk}\rfloor}[1|GCD(i, j)]\]

\[=\lfloor\frac{n}{xk}\rfloor\lfloor\frac{m}{xk}\rfloor\]

\[f(n)=\sum_{n|d}\mu(\frac{d}{n})g(d)\]

则\[ans(n, m)=f(1)=\sum_{d=1}^n\mu(d)g(d)\]

\[=\sum_{d=1}^n\mu(d)\lfloor\frac{n}{dk}\rfloor\lfloor\frac{m}{dk}\rfloor\]

[HDU1695]GCD

又\((x, y)\)和\((y,x)\)是等价的,要减去重复算的

假设\(b<d\),则最终\(ans=ans(b, d)-ans(b, b)/2\)

void init(){
    miu[1]=1;
    for(int i=2; i < N; i++) {
        if(!p[i]) p[++p[0]]=i, miu[i]=-1;
        for(int j=1; j <= p[0] && i*p[j] < N; j++){
            p[i*p[j]]=1; if(i%p[j] == 0) {miu[i*p[j]]=0; break;} else miu[i*p[j]]=-miu[i];
        }
    }
}
void solve(){
    init(); int T=read();
    for(int i=1; i <= T; i++){
        int a=read(), b=read(), c=read(), d=read(), k=read(); cout<<"Case "<<i<<": ";
        if(k == 0) {cout<<0<<endl; continue;} b/=k, d/=k;
        ll ans1=0, ans2=0, mn=min(b, d);
        for(int i=1; i <= mn; i++)
            ans1+=1LL*miu[i]*(b/i)*(d/i), ans2+=1LL*miu[i]*(mn/i)*(mn/i);
        cout<<ans1-ans2/2<<endl;
    }
}

[HAOI2011]Problem b

这题要容斥一下\(ans=ans(b, d)-ans(a-1, d)-ans(b, c-1)+ans(a-1, c-1)\),

还要整除分块,否则会\(TLE\)

void init(){
    p[1]=miu[1]=1;
    for(int i=2; i < N; i++) {
        if(!p[i]) p[++p[0]]=i, miu[i]=-1;
        for(int j=1, x; j <= p[0] && (x=p[j]*i) < N; j++){ p[x]=1;
            if(i%p[j] == 0) {miu[x]=0; break;} miu[x]=-miu[i];
        }
    }
    for(int i=1; i < N; i++) miu[i]+=miu[i-1];
}
ll cal(ll m, ll n){ m/=k, n/=k;
    ll ans=0, mn=min(n, m);
    for(int i=1, j; i <= mn; i=j+1){
        j=min(n/(n/i), m/(m/i));
        ans+=1LL*(miu[j]-miu[i-1])*(n/i)*(m/i);
    }
    return ans;
}
void solve(){
    int T=read(); init();
    while(T--){
        ll a=read(), b=read(), c=read(), d=read(); k=read();
        printf("%lld\n", cal(b, d)-cal(a-1, d)-cal(b, c-1)+cal(a-1, c-1));
    }
}

[POI2007]ZAP-Queries 这题\(ans=ans(n, m)\)

原文地址:https://www.cnblogs.com/zerolt/p/9295755.html

时间: 2025-01-08 18:09:24

[HDU1695]GCD + [HAOI2011]Problem b + [POI2007]ZAP-Queries【莫比乌斯反演】的相关文章

BZOJ 2301 [HAOI2011]Problem b (容斥+莫比乌斯反演+分块优化 详解)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2096  Solved: 909 [Submit][Status][Discuss] 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 Out

BZOJ 1101 [POI2007]Zap(莫比乌斯反演)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1101 [题目大意] 求[1,n][1,m]内gcd=k的情况 [题解] 考虑求[1,n][1,m]里gcd=k 等价于[1,n/k][1,m/k]里gcd=1 考虑求[1,n][1,m]里gcd=1 结果为sum(miu[d]*(n/d)*(m/d)) 预处理O(n^1.5) 由于n/d只有sqrt(n)种取值,所以可以预处理出miu[]的前缀和 询问时分段求和 [代码] #incl

【BZOJ】1101: [POI2007]Zap(莫比乌斯+分块)

http://www.lydsy.com/JudgeOnline/problem.php?id=1101 无限膜拜数论和分块orz 首先莫比乌斯函数的一些性质可以看<初等数论>或<具体数学>或贾志鹏的<线性筛法和积性函数> 我写一些笔记啥的吧.. 首先莫比乌斯函数的定义及一些性质(免去证明): $$\mu (n) =\begin{cases}1 & n=1\\(-1)^k & n=p_1p_2 \cdots p_k,质因子指数均为1且互不相同 \\0 &

P3455 [POI2007]ZAP-Queries(莫比乌斯反演)

思路 和YY的GCD类似但是更加简单了 类似的推一波公式即可 \[ F(n)=\sum_{n|d}f(d) \] \[ f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d) \] \[ F(d)=\lfloor\frac{n}{d}\rfloor\times\lfloor\frac{m}{d}\rfloor \] \[ f(x)=\sum_{x|d}\mu(\frac{d}{x})\times\lfloor\frac{n}{d}\rfloor\times\lfloor\frac

【BZOJ】2301: [HAOI2011]Problem b(莫比乌斯+分块)

http://www.lydsy.com/JudgeOnline/problem.php?id=2301 和这题不是差不多的嘛--[BZOJ]1101: [POI2007]Zap(莫比乌斯+分块) 唯一不同的地方是这题有下界.. 下界除以k的时候取上界,然后分块的时候因为有4个数,所以要分成4块来搞.. 然后就行了.. #include <cstdio> #include <cstring> #include <cmath> #include <string>

【莫比乌斯反演】BZOJ1101 [POI2007]zap

Description 回答T组询问,有多少组gcd(x,y)=d,x<=a, y<=b.T, a, b<=4e5. Solution 显然对于gcd=d的,应该把a/d b/d,然后转为gcd=1计算 计算用莫比乌斯反演相信大家都会 关键是有T组询问n^2会T 于是有这样一个优化可以做到每次sqrt(n) 每一次是ret+=mu[i]*(n/i)*(m/i) 可是除法向下取整所以会导致很多i的(n/i)*(m/i)一样 具体来说,向下取整得到的结果一定是约数所以对于(n/i)最多2sq

bzoj 1101 Zap —— 莫比乌斯反演

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1101 直接莫比乌斯反演. 代码如下: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const xn=5e5+5; int pri[xn],cnt,mu[xn]; bool vis[xn]; int rd()

[BZOJ1101&amp;BZOJ2301][POI2007]Zap [HAOI2011]Problem b|莫比乌斯反演

对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d. 我们可以令F[n]=使得n|(x,y)的数对(x,y)个数 这个很容易得到,只需要让x,y中都有n这个因子就好了,也就是[a/n]*[b/n]个数对(向下取整) 然后设题中所要求的为f[n],很容易得知,F[n]=∑f[d](n|d) 莫比乌斯反演可以得到f[n]=∑μ(d/n)F[d](n|d) 这样是O(n),然而数据范围5*10^4显然不能通过 f[n]=∑μ(d/n)[a/d][b/d]

BZOJ 2301([HAOI2011]Problem b-mobius反演)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2170  Solved: 934 [Submit][Status][Discuss] 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 Out