BZOJ 2301[HAOI2011]Problem b

2301: [HAOI2011]Problem b

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 5072  Solved: 2359
[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

之后同BZOJ 2818

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define LL long long
 5 const int maxn=50000;
 6 int mu[maxn+10],prime[maxn+10];
 7 int s[maxn+10];
 8 bool book[maxn+10];
 9 int T,a,b,c,d,k,cnt;
10 void ss()
11 {
12     mu[1]=1;
13     for(int i=2;i<=maxn;i++)
14     {
15         if(!book[i])
16         {
17             prime[++cnt]=i; 
18             mu[i]=-1;
19         }
20         for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++)
21         {
22             book[i*prime[j]]=true;
23             if(i%prime[j])
24                 mu[i*prime[j]]=-mu[i];
25             else  
26             {
27                 mu[i*prime[j]]=0;
28                 break;
29             }
30         }
31     }
32     for(int i=1;i<=maxn;i++)
33         s[i]=s[i-1]+mu[i];
34 }
35 LL caculate(int n,int m)
36 {
37     if(n>m)
38         swap(n,m);
39     int ans=0,last;
40     for(int i=1;i<=n;i=last+1)
41     {
42         last=min(n/(n/i),m/(m/i));
43         ans+=(s[last]-s[i-1])*(n/i)*(m/i);
44     }
45     return ans;
46 }
47 int main()
48 {
49     ss();
50     scanf("%d",&T);
51     while(T--)
52     {   
53         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
54         --a,--c;
55         a/=k,b/=k,c/=k,d/=k;
56         printf("%d\n",caculate(b,d)-caculate(a,d)-caculate(b,c)+caculate(a,c));
57     }
58 }
BZOJ 2301

 

posted @ 2017-07-11 15:57  avancent  阅读(...)  评论(...编辑  收藏