zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    C#泛型类的简单创建与使用
    线程、委托、lambda运算符的简单示例
    异步编程中使用帮助类来实现Thread.Start()的示例
    C#操作INI配置文件示例
    C#“简单加密文本器”的实现
    Java设计模式之模板模式(Template )
    java提取出一个字符串里面的Double类型数字
    阿里云服务器配置SSL证书成功开启Https(记录趟过的各种坑)
    Gson解决字段为空是报错的问题
    shiro 单点登录原理 实例
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4744314.html
Copyright © 2011-2022 走看看