Time Limit: 50 Sec Memory Limit: 256 MB
Submit: 1737 Solved: 749
对于给出的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)的个数
2 2 5 1 5 1 1 5 1 5 2
14 3
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000
题解:一个霸(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.