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
  • 相关阅读:
    hdu 5101 Select
    hdu 5100 Chessboard
    cf B. I.O.U.
    cf C. Inna and Dima
    cf B. Inna and Nine
    cf C. Counting Kangaroos is Fun
    Radar Installation 贪心
    spfa模板
    Sequence
    棋盘问题
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4744314.html
Copyright © 2011-2022 走看看