zoukankan      html  css  js  c++  java
  • 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}^asum_{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}^nmu(d)lfloorfrac a{kd} floorlfloorfrac b{kd} floor)

    连枚举倍数都不用。。。直接打个数论分块就行了。。。复杂度(O(Tsqrt 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
    ", res);
    	}
    	return 0;
    }
    

    40行一遍AC

    于NOIWC2019 Day2晚试机

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

    NOI Linux真TM难用,累死我了

  • 相关阅读:
    宝塔面板的数据库使用
    Spring MVC入门
    从分式第n项到线性递推——bostan-mori 算法的扩展应用
    计算几何专题训练
    博客整理
    wpf ScrollViewer自动滚到最上
    word2Vec笔记2021
    好用工具备份
    Samtools pick up seq
    Ryzen核显需要扩大显存吗?
  • 原文地址:https://www.cnblogs.com/oier/p/10321429.html
Copyright © 2011-2022 走看看