# [BZOJ 2301] [HAOI2011] Problem b

## 2301: [HAOI2011]Problem b

Time Limit: 50 Sec
Memory Limit: 256 MB

2
2 5 1 5 1
1 5 1 5 2

14
3

## HINT

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

【题解】莫比乌斯反演+前缀和处理即可。

 1 #include <cstdio>
2 #define min(x,y) x<y?x:y
3 using namespace std;
4 int mu[50010];
5 bool chk[50010];
6 int prime[50010],tot=0;
7 long long getsum(int x,int y) {
8     long long re=0;
9     int f=min(x,y),la;
10     for (int i=1;i<=f;i=la+1) {
11         la=min(x/(x/i),y/(y/i));
12         re+=(long long)(x/i)*(y/i)*(mu[la]-mu[i-1]);
13     }
14     return re;
15 }
16 int main() {
17     //scanf("%d",&n);
18     mu[1]=1;
19     for (int i=2;i<=50000;++i) {
20         if (!chk[i]) {
21             prime[++tot]=i;
22             mu[i]=-1;
23         }
24         for  (int j=1;j<=tot&&i*prime[j]<=50000;++j) {
25             chk[i*prime[j]]=1;
26             if(i%prime[j]==0) {
27                 mu[i*prime[j]]=0;
28                 break;
29             }
30             mu[i*prime[j]]=-mu[i];
31         }
32     }
33     mu[0]=0;
34     for (int i=2;i<=50000;++i) mu[i]+=mu[i-1];
35     int t;
36     scanf("%d",&t);
37     while(t--) {
38         int a,b,c,d,k;
39         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
40         printf("%lld\n",getsum(b/k,d/k)-getsum((a-1)/k,d/k)-getsum(b/k,(c-1)/k)+getsum((a-1)/k,(c-1)/k));
41     }
42     return 0;
43 }
View Code

posted @ 2015-06-23 20:10  TonyFang  阅读(96)  评论(0编辑  收藏