2301: [HAOI2011]Problem b

时间:2022-05-08
本文章向大家介绍2301: [HAOI2011]Problem b,主要内容包括2301: [HAOI2011]Problem b、Description、Input、Output、Sample Input、Sample Output、HINT、Source、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

2301: [HAOI2011]Problem b

Time Limit: 50 Sec  Memory Limit: 256 MB

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

Output

共n行,每行一个整数表示满足要求的数对(x,y)的个数

Sample Input

2 2 5 1 5 1 1 5 1 5 2

Sample Output

14 3

HINT

100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000

Source

题解:一个霸(dou)气(bi)的莫比乌斯反演,然后没啥了,开始瞎搞——不过这题里面有个重要的思想——既然直接求某“悬空”区间的结果(“悬空”区间即像本题中第一个值设定为[a,b],而不是(0,b]),那么为何不用好求的求出来然后容斥原理加加减减呢——嗯哼么么哒

 1 const maxn=150000;
 2 var
 3    i,j,k,l,m,n,x1,y1,x2,y2,z:longint;
 4    a,b:array[0..maxn] of longint;
 5 procedure swap(var x,y:longint);
 6           var z:longint;
 7           begin
 8                z:=x;x:=y;y:=z;
 9           end;
10 function doit(x,y:longint):int64;
11          var i,j,k:longint;
12          begin
13               doit:=0;
14               if x>y then swap(x,y);
15               if x=0 then exit(0);
16               i:=1;
17               while i<=x do
18                     begin
19                          if (x div (x div i))<(y div (y div i)) then
20                             k:=x div (x div i)
21                          else k:=y div (y div i);
22                          inc(doit,(b[k]-b[i-1])*int64(x div i)*int64(y div i));
23                          i:=k+1;
24                     end;
25          end;
26 begin
27      for i:=2 to maxn do
28          begin
29               if a[i]<>0 then continue;
30               for j:=i to maxn div i do a[i*j]:=i;
31          end;
32      b[1]:=1;
33      for i:=2 to maxn do
34          if a[i]=0 then b[i]:=-1 else
35             if ((i div a[i]) mod a[i])=0 then b[i]:=0 else
36                b[i]:=-b[i div a[i]];
37      for i:=2 to maxn do b[i]:=b[i]+b[i-1];
38      readln(n);
39      for i:=1 to n do
40          begin
41               readln(x1,y1,x2,y2,z);
42               x1:=(x1-1) div z;y1:=y1 div z;
43               x2:=(x2-1) div z;y2:=y2 div z;
44               writeln(doit(y1,y2)-doit(x1,y2)-doit(y1,x2)+doit(x1,x2));
45          end;
46      readln;
47 end.