luogu3455 [POI2007]ZAP-Queries 简单的莫比乌斯反演

link

ms是莫比乌斯反演里最水的题。。。

题意:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d。

多组询问, T<=50000,d,a,b<=50000

稍微推下shizi

\(\sum_{i=1}^a\sum_{j=1}^b[\gcd(i,j)=d]\)

\(=\sum_{i=1}^{a/k}\sum_{j=1}^{b/k}[\gcd(i,j)=1]\)

\(=\sum_{i=1}^{a/k}\sum_{j=1}^{b/k}\sum_{d|i,d|j}\mu(d)\)

\(=\sum_{i=1}^{a/k}\sum_{j=1}^{b/k}\sum_{d|i,d|j}\mu(d)\)

\(=\sum_{d=1}^n\mu(d)\lfloor\frac a{kd}\rfloor\lfloor\frac b{kd}\rfloor\)

连枚举倍数都不用。。。直接打个数论分块就行了。。。复杂度\(O(T\sqrt n)\)

#include <cstdio>
#include <functional>
using namespace std;

bool visit[50010];
int prime[50010], mu[50010], tot, fuck = 50000;

int main()
{
    mu[1] = 1;
    for (int i = 2; i <= fuck; i++)
    {
        if (visit[i] == false) prime[++tot] = i, mu[i] = -1;
        for (int j = 1; j <= tot && i * prime[j] <= fuck; j++)
        {
            visit[i * prime[j]] = true;
            if (i % prime[j] == 0) break;
            mu[i * prime[j]] = -mu[i];
        }
        mu[i] += mu[i - 1];
    }
    int t;
    scanf("%d", &t);
    while (t --> 0)
    {
        int n, m, k;
        scanf("%d%d%d", &n, &m, &k);
        n /= k, m /= k;
        int res = 0;
        if (n > m) swap(n, m);
        for (int i = 1, j; i <= n; i = j + 1)
        {
            j = min(n / (n / i), m / (m / i));
            res += (mu[j] - mu[i - 1]) * (n / i) * (m / i);
        }
        printf("%d\n", res);
    }
    return 0;
}

40行一遍AC

于NOIWC2019 Day2晚试机

日推里出现的题,竟然挺水

NOI Linux真TM难用,累死我了

原文地址:https://www.cnblogs.com/oier/p/10321429.html

时间: 2024-07-31 13:03:46

luogu3455 [POI2007]ZAP-Queries 简单的莫比乌斯反演的相关文章

[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 2440 简单莫比乌斯反演

题目大意: 找第k个非平方数,平方数定义为一个数存在一个因子可以用某个数的平方来表示 这里首先需要考虑到二分才可以接下来做 二分去查找[1 , x]区间内非平方数的个数,后面就是简单的莫比乌斯反演了 容斥原理的思想,首先考虑所有数都属于非平方数 那么就是x 然后对于每一个平方数都要减去,但是这里应该只考虑质数的平方数就可以了 那么就扩展为x - x/(2^2) - x/(3^2) - x/(k^2).... 然后因为中间存在重复减的那么要加回来 -> x - x/(2^2) - x/(3^3) 

BZOJ1101: [POI2007]Zap(莫比乌斯反演)

1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2951  Solved: 1293[Submit][Status][Discuss] Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d.作为FGD的同学,FGD希望得到你的帮助. Input 第一行包含一个正整数n,表示一共有n组询问.(1

bzoj 1101 [POI2007]Zap - 莫比乌斯反演

Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d.作为FGD的同学,FGD希望得到你的帮助. Input 第一行包含一个正整数n,表示一共有n组询问.(1<=n<= 50000)接下来n行,每行表示一个询问,每行三个 正整数,分别为a,b,d.(1<=d<=a,b<=50000) Output 对于每组询问,输出到输出文件zap.out一个正

【莫比乌斯反演】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

【Luogu3768】简单的数学题(莫比乌斯反演,杜教筛)

[Luogu3768]简单的数学题(莫比乌斯反演,杜教筛) 题面 洛谷 \[求\sum_{i=1}^n\sum_{j=1}^nijgcd(i,j)\] $ n<=10^9$ 题解 很明显的把\(gcd\)提出来 \[\sum_{d=1}^nd\sum_{i=1}^n\sum_{j=1}^nij[gcd(i,j)==d]\] 习惯性的提出来 \[\sum_{d=1}^nd^3\sum_{i=1}^{n/d}\sum_{j=1}^{n/d}ij[gcd(i,j)==1]\] 后面这玩意很明显的来一发

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()

浅谈算法——莫比乌斯反演

前言 莫比乌斯反演(又称懵逼钨丝繁衍),那种让人看了就懵逼的东西(其实是我太菜了) 莫比乌斯反演在知道之后对解题十分有帮助,\(O(n)\)的柿子分分钟化成\(O(\sqrt n)\) 那么,什么是莫比乌斯反演呢? 莫比乌斯反演 1.莫比乌斯反演 如果说,有\(f(n)\)和\(g(n)\)是定义在正整数集合上的两个函数,并且满足 \[f(n)=\sum\limits_{d|n} g(d)\] 那么就有 \[g(n)=\sum\limits_{d|n} f(\dfrac{n}{d})\times

莫比乌斯反演入门

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