# 【莫比乌斯反演+容斥】BZOJ2301-[HAOI2011]Problem b(成为权限狗的第一题纪念！)

【题目大意】

【思路】

“怎么又是你系列……”思路和分块方法分别参见：🐈🐩 ←岛国输入法超级好用啊wwww

【错误点】

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 typedef long long ll;
7 const int MAXN=50000+50;
8 const int INF=0x7fffffff;
9 int a,b,c,d,k;
10 int miu[MAXN],prime[MAXN],pnum;
11 ll miusum[MAXN];
12
13 void getmiu(int maxn)
14 {
15     memset(miusum,0,sizeof(miusum));
16     miu[1]=miusum[1]=1;
17     for (int i=2;i<maxn;i++) miu[i]=-INF;
18     for (int i=2;i<maxn;i++)
19     {
20         if (miu[i]==-INF)
21         {
22             miu[i]=-1;
23             prime[++pnum]=i;
24         }
25         for (int j=1;j<=pnum;j++)
26         {
27             if (i*prime[j]>=maxn) break;
28             if (i%prime[j]==0) miu[i*prime[j]]=0;
29                 else miu[i*prime[j]]=-miu[i];
30
31         }
32         miusum[i]=miusum[i-1]+miu[i];
33     }
34 }
35
36 ll solve(int b,int d,int k)
37 {
38     b/=k;d/=k;
39     int ub=min(b,d),pos;
40     ll ret=0;
41     for (int i=1;i<=ub;i=pos+1)
42     {
43         pos=min(b/(b/i),d/(d/i));
44         ret+=(ll)(miusum[pos]-miusum[i-1])*(ll)(b/i)*(ll)(d/i);
45     }
46     return ret;
47 }
48
49 int main()
50 {
51     int T;
52     getmiu(MAXN-1);
53     scanf("%d",&T);
54     while (T--)
55     {
56         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
57         ll ans=solve(b,d,k)-solve(a-1,d,k)-solve(c-1,b,k)+solve(a-1,c-1,k);
58         printf("%lld\n",ans);
59     }
60 }

posted @ 2016-07-27 15:23  iiyiyi  阅读(116)  评论(0编辑  收藏