• bzoj 2301 [HAOI2011]Problem b(莫比乌斯反演+分块优化)


    题意对于给出的n个询问,每次求有多少个数对(x,y),满足axbcyd,且gcd(x,y) = kgcd(x,y)函数为xy的最大公约数。

    1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000

    思路:莫比乌斯反演,ans=solve(b/k,d/k)-solve((a-1)/k,d/k)-solve(b/k,(c-1)/k)+solve((a-1)/k,(c-1)/k)

    代码1:超时。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN=100000;
    bool check[MAXN+10];
    int prime[MAXN+10];
    int mu[MAXN+10];
    void Mobius(){
        memset(check,false,sizeof(check));
        mu[1]=1;
        int tot=0;
        for(int i=2;i<=MAXN;i++){
            if(!check[i]){
                prime[tot++]=i;
                mu[i]=-1;
            }
            for(int j=0;j<tot;j++){
                if(i*prime[j]>MAXN)break;
                check[i*prime[j]]=true;
                if(i%prime[j]==0){
                    mu[i*prime[j]]=0;
                    break;
                }
                else{
                    mu[i*prime[j]]=-mu[i];
                }
            }
        }
    }
    //找[1,n],[1,m]内互质的数的对数
    long long solve(int n,int m){
        long long ans=0;
        if(n>m)swap(n,m);
        for(int i=1;i<=n;i++)
            ans+=(long long)mu[i]*(n/i)*(m/i);
        return ans;
    }
    
    int main(){
        Mobius();
        int t;
        int a,b,c,d,k;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
            long long ans=solve(b/k,d/k)-solve((a-1)/k,d/k)-solve(b/k,(c-1)/k)+solve((a-1)/k,(c-1)/k);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    代码2:用到分块优化。待研究。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN=100000;
    bool check[MAXN+10];
    int prime[MAXN+10];
    int mu[MAXN+10];
    void Mobius(){
        memset(check,false,sizeof(check));
        mu[1]=1;
        int tot=0;
        for(int i=2;i<=MAXN;i++){
            if(!check[i]){
                prime[tot++]=i;
                mu[i]=-1;
            }
            for(int j=0;j<tot;j++){
                if(i*prime[j]>MAXN)break;
                check[i*prime[j]]=true;
                if(i%prime[j]==0){
                    mu[i*prime[j]]=0;
                    break;
                }
                else{
                    mu[i*prime[j]]=-mu[i];
                }
            }
        }
    }
    int sum[MAXN+10];
    //找[1,n],[1,m]内互质的数的对数
    long long solve(int n,int m){
        long long ans=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));
            ans+=(long long)(sum[la]-sum[i-1])*(n/i)*(m/i);
        }
        return ans;
    }
    
    int main(){
        Mobius();
        sum[0]=0;
        for(int i=1;i<=MAXN;i++)
            sum[i]=sum[i-1]+mu[i];
        int t;
        int a,b,c,d,k;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
            long long ans=solve(b/k,d/k)-solve((a-1)/k,d/k)-solve(b/k,(c-1)/k)+solve((a-1)/k,(c-1)/k);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    用vs调试sql存储过程
    Html插入Flash.object.embed.swf各个参数值详解介绍[等比例缩放]
    SQL SERVER分区具体例子详解
    C#身份证识别相关技术
    C#调用Java方法(详细实例)
    Visual Studio各版本工程文件之间的转换
    彻底解决asp.net mvc5.2.2:vs2013 cshtml视图文件报错(当前上下文中不存在名称“model”,ViewBag,Url)
    HTML 5 Web 本地存储
    让WeuiPicker隐藏日期中的日,只保留年月
    javascript获取值
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4744314.html
Copyright © 2020-2023  润新知