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≤d≤50000,1≤k≤50000

Solution:

  本题莫比乌斯反演+简单容斥。

  先考虑$1,n$和$1,m$范围内的情况,那么做法就和上题的ZAP类似,过程就不多赘述。

  那么容斥一下,答案就是$(b,d)-(a-1,d)-(b,c-1)+(a-1,c-1)$啦。

  时间复杂度$O(q\sqrt n)$。

代码:

/*Code by 520 -- 9.10*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=50005;
int a,b,c,d,k,ans;
int mu[N],prime[N],cnt;
bool isprime[N];

int gi(){
    int a=0;char x=getchar();
    while(x<‘0‘||x>‘9‘)x=getchar();
    while(x>=‘0‘&&x<=‘9‘)a=(a<<3)+(a<<1)+(x^48),x=getchar();
    return a;
}

il int solve(int n,int m){
    int ans=0,p;
    if(n>m) swap(n,m);
    n/=k,m/=k;
    for(int i=1;i<=n;i=p+1){
        p=min(n/(n/i),m/(m/i));
        ans+=(n/i)*(m/i)*(mu[p]-mu[i-1]);
    }
    return ans;
}

int main(){
    mu[1]=1;
    For(i,2,50000){
        if(!isprime[i]) mu[i]=-1,prime[++cnt]=i;
        for(RE int j=1;j<=cnt&&prime[j]*i<=50000;j++){
            isprime[i*prime[j]]=1;
            if(i%prime[j]==0)break;
            mu[i*prime[j]]=-mu[i];
        }
    }
    For(i,1,50000) mu[i]+=mu[i-1];
    int T=gi();
    while(T--){
        a=gi(),b=gi(),c=gi(),d=gi(),k=gi();
        printf("%d\n",solve(b,d)-solve(a-1,d)-solve(b,c-1)+solve(a-1,c-1));
    }
    return 0;
}    

原文地址:https://www.cnblogs.com/five20/p/9633881.html

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

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=

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$

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

BZOJ 2302: [HAOI2011]Problem c( dp )

dp(i, j)表示从i~N中为j个人选定的方案数, 状态转移就考虑选多少人为i编号, 然后从i+1的方案数算过来就可以了. 时间复杂度O(TN^2) --------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long lo

[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

BZOJ 2301([HAOI2011]Problem b-mobius反演)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2170  Solved: 934 [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 Out

BZOJ 2301 [HAOI2011]Problem b (容斥+莫比乌斯反演+分块优化 详解)

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 2096  Solved: 909 [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 Out

HAOI2011 problem b

其实就是容斥原理了 代码: 1 uses math; 2 const maxn=55000; 3 var i,n,a,b,c,d,w,tot:longint; 4 ans:int64; 5 sum,mu,p:array[0..maxn] of int64; 6 procedure get; 7 var i,j,k:longint; 8 check:array[0..maxn] of boolean; 9 begin 10 fillchar(check,sizeof(check),false);

BZOJ 2302: [HAOI2011]Problem c [DP 组合计数]

2302: [HAOI2011]Problem c Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 648  Solved: 355[Submit][Status][Discuss] Description 给n个人安排座位,先给每个人一个1~n的编号,设第i个人的编号为ai(不同人的编号可以相同),接着从第一个人开始,大家依次入座,第i个人来了以后尝试坐到ai,如果ai被占据了,就尝试ai+1,ai+1也被占据了的话就尝试ai+2,……,如果一直