[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 #include<iostream>
 3 using namespace std;
 4 const int M=50009;
 5 int k,prime[M],mu[M],s[M];
 6 bool flag[M];
 7
 8 int read()
 9 {
10     int x=0; char ch=getchar();
11     while (ch<‘0‘ || ch>‘9‘) ch=getchar();
12     while (ch>=‘0‘ && ch<=‘9‘) x=(x<<1)+(x<<3)+ch-48,ch=getchar();
13     return x;
14 }
15
16 void getmu(int n)
17 {
18     mu[1]=1;
19     int i,j,k,cnt=0;
20     for (i=2;i<n;++i)
21     {
22         if (!flag[i]) prime[++cnt]=i,mu[i]=-1;
23         for (j=1;j<=cnt && (k=i*prime[j])<n;++j)
24         {
25             flag[k]=1;
26             if (!(i%prime[j])) { mu[k]=0; break; }
27             mu[k]=-mu[i];
28         }
29     }
30     for (i=1;i<n;++i) s[i]=s[i-1]+mu[i];
31 }
32
33 int sum(int n,int m)
34 {
35     if (n>m) swap(n,m);
36     n=n/k,m=m/k;
37     int i,j,ans=0;
38     for (i=1;i<=n;i=j+1)
39     {
40         j=min(n/(n/i),m/(m/i));
41         ans=ans+(s[j]-s[i-1])*(n/i)*(m/i);
42     }
43     return ans;
44 }
45
46 int main()
47 {
48     getmu(M);
49     for (int T=read();T;--T)
50     {
51         int a=read(),b=read(),c=read(),d=read();k=read();
52         printf("%d\n",sum(b,d)-sum(a-1,d)-sum(c-1,b)+sum(a-1,c-1));
53     }
54     return 0;
55 }
时间: 2024-10-13 18:27:21

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

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 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

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-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