Pentium.Labs

System全家桶：https://zhuanlan.zhihu.com/c_1238468913098731520

• 随笔 - 233
• 文章 - 0
• 评论 - 39
• 引用 - 0

BZOJ2301 莫比乌斯反演

Ans=G(b/k,d/k)-G((a-1)/k,d/k)-G(b/k,(c-1)/k)+G((a-1)/k,(c-1)/k)

//calc G(a,b)

LL _G(int a,int b)          //朴素算法
{
int tx=min(a,b),ty=max(a,b);
LL ans = 0;
for(int i = 1; i <= tx; i++)
ans += (LL)mu[i]*(tx/i)*(ty/i);
return ans;
}

LL G(int n,int m)           //加分块优化
{
LL ans = 0;
if(n > m)   swap(n,m);
for(int i = 1, la = 0; i <= n; i = la+1)
{
la = min(n/(n/i),m/(m/i));
ans += (LL)(msum[la] - msum[i-1])*(n/i)*(m/i);      //事先预处理：msum[n]=SUM(mu[1..n])
}
return ans;
}

 1 #include <iostream>
2 #include <cstring>
3 #include <cmath>
4 #include <cstdio>
5 using namespace std;
6 #define LL long long
7 #define MMX 50100
8 LL mu[MMX],msum[MMX];
9 bool check[MMX];
10 int prime[MMX];
11 int a,b,c,d,k,T;
12
13 void Moblus()
14 {
15     memset(check,false,sizeof(check));
16     mu[1] = 1;
17     int tot = 0;
18     for(int i = 2; i <= MMX; i++)
19     {
20         if( !check[i] )
21         {
22             prime[tot++] = i;
23             mu[i] = -1;
24         }
25         for(int j = 0; j < tot; j++)
26         {
27             if(i * prime[j] > MMX) break;
28             check[i * prime[j]] = true;
29             if( i % prime[j] == 0)
30             {
31                 mu[i * prime[j]] = 0;
32                 break;
33             }
34             else
35             {
36                 mu[i * prime[j]] = -mu[i];
37             }
38         }
39     }
40     msum[1]=mu[1];
41     for (int i=2;i<=MMX;i++)
42         msum[i]=msum[i-1]+mu[i];
43 }
44
45 //calc G(a,b)
46 LL _G(int a,int b)          //朴素算法
47 {
48     int tx=min(a,b),ty=max(a,b);
49     LL ans = 0;
50     for(int i = 1; i <= tx; i++)
51         ans += (LL)mu[i]*(tx/i)*(ty/i);
52     return ans;
53 }
54
55 LL G(int n,int m)           //加分块优化
56 {
57     LL ans = 0;
58     if(n > m)   swap(n,m);
59     for(int i = 1, la = 0; i <= n; i = la+1)
60     {
61         la = min(n/(n/i),m/(m/i));
62         ans += (LL)(msum[la] - msum[i-1])*(n/i)*(m/i);      //事先预处理：msum[n]=SUM(mu[1..n])
63     }
64     return ans;
65 }
66
67 int main()
68 {
69     //freopen("in.txt","r",stdin);
70     //freopen("out.txt","w",stdout);
71
72     cin>>T;
73     Moblus();
74     while (T--)
75     {
76         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
77         //cout<<G(b/k,d/k)<<"  "<<G((a-1)/k,d/k)<<"  "<<G(b/k,(c-1)/k)<<"  "<<G((a-1)/k,(c-1)/k)<<endl;
78         LL res=G(b/k,d/k)-G((a-1)/k,d/k)-G(b/k,(c-1)/k)+G((a-1)/k,(c-1)/k);
79         printf("%lld\n",res);
80     }
81     return 0;
82 }
View Code

 1005 root 1002 Accepted 380K 47400MS G++ 1.6K 2014-11-15 15:37:03

 1014 root 1002 Accepted 952K 6011MS G++ 1.81K 2014-11-15 17:17:59

posted on 2014-11-15 15:57  Pentium.Labs  阅读(122)  评论(0编辑  收藏

Pentium.Lab Since 1998