题解 P2522 【[HAOI2011]Problem b】

题目链接

Solution [HAOI2011]Problem b

题目大意:多组数据,给定\(a,b,c,d,k\)\(\sum_{i=a}^b\sum_{j=c}^d[gcd(i,j)=k]\)

莫比乌斯反演,容斥


解析:

这题相当于[POI2007]ZAP-Queries加强了一下,我们知道\(\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k]\),简单容斥一下就可以知道答案了

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 1e5;
int vis[maxn],mu[maxn];
inline int sum(int a,int b){return mu[b] - mu[a - 1];}
vector<int> pri;
inline void sieve(){
    mu[1] = 1;
    for(int i = 2;i < maxn;i++){
        if(!vis[i]){
            pri.push_back(i);
            mu[i] = -1;
        }
        for(int x : pri){
            if(1ll * x * i >= maxn)break;
            vis[i * x] = 1;
            if(i % x){
                mu[i * x] = mu[i] * mu[x];
            }else{
                mu[i * x] = 0;
                break;
            }
        }
    }
    for(int i = 1;i < maxn;i++)mu[i] += mu[i - 1];
}
int t,a,b,c,d,k;
inline int query(int a,int b,int d){
    int n = a / d,m = b / d,res = 0;
    for(int l = 1,r;l <= min(n,m);l = r + 1){
        r = min(n / (n / l),m / (m / l));
        res += sum(l,r) * (n / l) * (m / l);
    }
    return res;
}
inline void solve(){
    cin >> a >> b >> c >> d >> k;
    cout << query(b,d,k) + query(a - 1,c - 1,k) - query(a - 1,d,k) - query(b,c - 1,k) << '\n';
}
int main(){ 
    sieve();
    cin >> t;
    while(t--)solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/colazcy/p/12238506.html