P2522 [HAOI2011]Problem b 题解

莫比乌斯反演

ACWing215的升级版

直接计算啊a<=i<=b,c<=j<=d的gcd(x,y)==k的个数不太好计算,因为我们很多时候都是从一开始枚举,而不是从一个大于1的数开始枚举,[x,y]范围内d的倍数也无法直接计算

仔细一看这就是一个二维偏序,二维前缀和即可

#include<bits/stdc++.h>
using namespace std;

#define go(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;

const int N=50000+10;

//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
//char buf[1<<21],*p1=buf,*p2=buf;
int u[N],sum[N],p[N],tot=0;
bool vis[N];

template<typename T> inline void read(T &x){
    x=0;char f=1,c=getchar();
    while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); }
    while(isdigit(c)){ x=x*10+c-'0'; c=getchar(); }
    x*=f;
}

void mobius(){
    u[1]=1;
    go(i,2,50000){
        if(!vis[i]) p[++tot]=i,u[i]=-1;
        for(int j=1;j<=tot&&p[j]*i<=50000;j++){
            vis[i*p[j]]=1;
      if(i%p[j]==0)break;//u函数有平方因子时为0
      else u[p[j]*i]=-u[i];//可能有平方因子,也可能没有,但是没有时不影响答案
        }
    }
    go(i,1,50000) sum[i]=sum[i-1]+u[i];
}

int calc(int a,int b,int d){
    int ans=0;
    a/=d,b/=d;
    if(a>b) swap(a,b);
    for(int d=1,nd;d<=a;d=nd+1){
        nd=min(a/(a/d),b/(b/d));
        ans+=a/d*(b/d)*(sum[nd]-sum[d-1]);
    }
    return ans;
}

signed main(){
    //freopen("input.txt","r",stdin);
    //freopen("put.txt","w",stdout);
    int n;read(n);
    int a,b,c,d,e;
    mobius();
    while(n--){
        int ans=0;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
        printf("%d\n",calc(b,d,e)-calc(a-1,d,e)-calc(b,c-1,e)+calc(a-1,c-1,e));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/White-star/p/11399103.html

时间: 2024-10-08 12:47:39

P2522 [HAOI2011]Problem b 题解的相关文章

洛谷P2522 - [HAOI2011]Problem b

Portal Description 进行\(T(T\leq10^5)\)次询问,每次给出\(x_1,x_2,y_1,y_2\)和\(d\)(均不超过\(10^5\)),求\(\sum_{i=x_1}^{x_2} \sum_{j=y_1}^{y_2} [gcd(i,j)=d]\). Solution 莫比乌斯反演入门题. 设\(calc(n,m)\)表示\(i\in[1,n],j\in[1,m]\)且\(gcd(i,j)=d\)的数对\((i,j)\)的个数.那么简单地进行容斥,可知\(ans=

[HAOI2011]Problem b 题解

题目大意: 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y)=k. 思路: 设f(k)为当1≤x≤n,1≤y≤m,且n≤m,使gcd(x,y)=k的数对(x,y)的对数,g(k)为当1≤x≤n,1≤y≤m,且n≤m,使k|gcd(x,y)的数对(x,y)的对数.则,莫比乌斯反演,得.和会有连续的一段相同且相同的为一定连续的一段,可证最多有2√n和2√m段,分块处理,对于每个询问可O(√n)解决. 代码: 1 #include<cstdio> 2

P2522 [HAOI2011]Problem b

题目描述 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 输入输出格式 输入格式: 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k 输出格式: 共n行,每行一个整数表示满足要求的数对(x,y)的个数 输入输出样例 输入样例#1: 2 2 5 1 5 1 1 5 1 5 2 输出样例#1: 14 3 说明 100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c

Luogu P2522 [HAOI2011]Problem b 莫比乌斯反演

设$f(d)=\sum_{i=1}^N\sum_{j=1}^M[gcd(i,j)==d],\\F(n)=\sum_{n|d}f(d)=\lfloor \frac{N}{n} \rfloor \lfloor \frac{M}{n} \rfloor$ 则$f(n)$ $=\sum_{n|d}\mu(\frac{n}{d})F(d)$ $=\sum_{n|d}\mu(\frac{n}{d})\lfloor \frac{N}{d} \rfloor \lfloor \frac{M}{d} \rfloor$

[BZOJ 2301] [HAOI2011] Problem b

2301: [HAOI2011]Problem b Time Limit: 50 SecMemory Limit: 256 MB Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Output 共n行,每行一个整数表示满足要求的数对(x,y)的个数 Sample Input 2 2 5 1 5

2301: [HAOI2011]Problem b

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 1737  Solved: 749[Submit][Status][Discuss] Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数n,接下来n行每行五个整数,分别表示a.b.c.d.k Outpu

【BZOJ2298】[HAOI2011]problem a DP

[BZOJ2298][HAOI2011]problem a Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi Output 一个整数,表示最少有几个人说谎 Sample Input 3 2 0 0 2 2 2 Sample Output 1 HINT 100%的数据满足: 1≤n≤100000   0≤

BZOJ 2298: [HAOI2011]problem a 动态规划

2298: [HAOI2011]problem a Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=2298 Description 一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi Outp

[luogu] P2519 [HAOI2011]problem a (贪心)

P2519 [HAOI2011]problem a 题目描述 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同的分数) 输入输出格式 输入格式: 第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai.bi 输出格式: 一个整数,表示最少有几个人说谎 输入输出样例 输入样例#1: 复制 3 2 0 0 2 2 2 输出样例#1: 复制 1 说明 100%的数据满足: 1≤n≤100000 0≤ai