zoukankan      html  css  js  c++  java
  • BZOJ1011 莫比乌斯反演(基础题

    【题目链接】 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(mu[d]*(n/d)*(m/d))

        预处理O(n^1.5)

        由于n/d只有sqrt(n)种取值,所以可以预处理出miu[]的前缀和 询问时分段求和

    【代码】

     
    #include<bits/stdc++.h>
    #define  ll long long
    using namespace std;
    const int N = 1e5 + 5;
    int t;
    //线性筛法求莫比乌斯函数
    bool vis[N + 10];
    int pri[N + 10];
    int mu[N + 10];
    int sum[N];
     
    void mus() {
        memset(vis, 0, sizeof(vis));
        mu[1] = 1;
        int tot = 0;
        for (int i = 2; i < N; i++) {
            if (!vis[i]) {
                pri[tot++] = i;
                mu[i] = -1;
            }
            for (int j = 0; j < tot && i * pri[j] < N; j++) {
                vis[i * pri[j]] = 1;
                if (i % pri[j] == 0) {
                    mu[i * pri[j]] = 0;
                    break;
                }
                else  mu[i * pri[j]] = -mu[i];
            }
        }
        sum[1]=1;
        for(int i=2;i<N;i++) sum[i]=sum[i-1]+mu[i];
    }
    int n,m,k;
    ll cal(int x,int y){
        int ma=min(x,y);
        ll ans=0;
        for(int i=1,j;i<=ma;i=j+1){
            j=min(x/(x/i),y/(y/i));
            if(j>=ma) j=ma;
            ans+=(sum[j]-sum[i-1])*(x/i)*(y/i);//此区间内x/i与y/i均为定值
        }
        return ans;
    }
    int main() {
        mus();
        scanf("%d",&t);
        for(int i=0;i<t;i++){
            cin>>n>>m>>k;
            cout<<cal(n/k,m/k)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    字符编码ANSI和ASCII区别、Unicode和UTF-8区别
    《非暴力沟通》读后感
    软件测试
    报表导出测试点
    如何设计测试用例
    国密算法sm2.sm3.sm4
    免杀原理与实践
    SQL注入攻击
    网络攻防实践 第十周作业
    网络攻防实践第九周
  • 原文地址:https://www.cnblogs.com/mj-liylho/p/9572461.html
Copyright © 2011-2022 走看看