码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ_2820_YY的GCD_莫比乌斯反演

时间:2018-02-05 12:31:26      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:==   ace   gpo   int   质数   algo   fine   gcd   pac   

BZOJ_2820_YY的GCD_莫比乌斯反演

题意&分析:
技术分享图片

首先f[i]非积性,但可以通过μ处理,所以我们考虑线筛

f[i*p]=μ[i*p/p‘];

1.当i为质数时f[i]=1;

2.当i%prime[j]==0时i*prime[j]中有两个相同因子的质数乘积,即p=p‘,则f[i*prime[j]]=μ[i];

3.当i%prime[j]!=0时,p!=p‘的情况对f的值有影响.当p‘!=p时μ[i*p/p‘]=-f[i],f[i*prime[j]]=μ[i]-f[i];

再记录下f[i]的前缀和,分块计算

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 using namespace std;
 5 #define LL long long
 6 int prime[4000010],vis[10000100],miu[10000100],f[10000100],sum[10000100],cnt;
 7 int T,n,m;
 8 inline void init()
 9 {
10     miu[1]=1;
11     for(int i=2;i<=10000000;i++)
12     {
13         if(!vis[i])
14         {
15             miu[i]=-1;
16             f[i]=1;
17             prime[++cnt]=i;    
18         }
19         for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
20         {
21             vis[i*prime[j]]=1;
22             if(i%prime[j]==0)
23             {
24                 miu[i*prime[j]]=0;
25                 f[i*prime[j]]=miu[i];
26                 break;
27             }
28             miu[i*prime[j]]=-miu[i];
29             f[i*prime[j]]=miu[i]-f[i];
30         }
31         sum[i]=sum[i-1]+f[i];
32     }
33 }
34 int main()
35 {
36     init();
37     scanf("%d",&T);
38     while(T--)
39     {
40         scanf("%d%d",&n,&m);
41         if(n>m)swap(n,m);
42         int lst;
43         LL ans=0;
44         for(int i=1;i<=n;i=lst+1)
45         {
46             lst=min(n/(n/i),m/(m/i));
47             ans+=1ll*(sum[lst]-sum[i-1])*(n/i)*(m/i);
48         }
49         printf("%lld\n",ans);
50     }
51 }
52  

 

BZOJ_2820_YY的GCD_莫比乌斯反演

标签:==   ace   gpo   int   质数   algo   fine   gcd   pac   

原文地址:https://www.cnblogs.com/suika/p/8416704.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!