2301: [HAOI2011]Problem b

传送门

一个莫比乌斯反演的模板题。

以前的代码。虽然我完全不记得我写过。

//Achen
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=50000+299;
int T,a,b,c,d,k,tot,bo[maxn],prime[maxn],mu[maxn],sum[maxn]; 

void make_mu(){
    mu[1]=1; sum[1]=1;
    for(int i=2;i<=maxn;i++){
        if(!bo[i]) {prime[++tot]=i; mu[i]=-1;}
        for(int j=1;j<=tot&&prime[j]*i<=maxn;j++){
            if(i%prime[j]==0){
                bo[prime[j]*i]=1;
                mu[prime[j]*i]=0;
                break;
            }
            else {
            bo[prime[j]*i]=1;
            mu[prime[j]*i]=mu[i]*(-1);
            }
        }
        sum[i]=sum[i-1]+mu[i];
    }
}

int f(int n,int m){
    n/=k; m/=k;
    int t=min(n,m),last,ans=0;
    for(int i=1;i<=t;i=last+1){
        last=min(n/(n/i),m/(m/i));
        ans+=(sum[last]-sum[i-1])*(n/i)*(m/i);    
    }
    return ans;
}

int cul(int a,int b,int c,int d){
    int res=0; 
    res+=f(b,d);
    res-=f(a-1,d);
    res-=f(b,c-1);
    res+=f(a-1,c-1);
    return res;
}

int main() {
   scanf("%d",&T);
   make_mu();
   while(T--){
       scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
       printf("%d
",cul(a,b,c,d));
   }
   return 0;
}
View Code
原文地址:https://www.cnblogs.com/Achenchen/p/8419153.html