nyoj CO-PRIME 莫比乌斯反演

CO-PRIME

时间限制:1000 ms  |  内存限制:65535 KB

难度:3

描述

This problem is so easy! Can you solve it?

You are given a sequence which contains n integers a1,a2……an, your task is to find how many pair(ai, aj)(i < j) that ai and aj is co-prime.

输入
There are multiple test cases.
Each test case conatains two line,the first line contains a single integer n,the second line contains n integers.
All the integer is not greater than 10^5.
输出
For each test case, you should output one line that contains the answer.
样例输入
3
1 2 3
样例输出
3

思路: http://blog.csdn.net/lyhvoyage/article/details/38455415应该是出题的人吧。

分析:莫比乌斯反演。

此题中,设F(d)表示n个数中gcd为d的倍数的数有多少对,f(d)表示n个数中gcd恰好为d的数有多少对,

则F(d)=∑f(n) (n % d == 0)

f(d)=∑mu[n / d] * F(n) (n %d == 0)

上面两个式子是莫比乌斯反演中的式子。

所以要求互素的数有多少对,就是求f(1)。

而根据上面的式子可以得出f(1)=∑mu[n] * F(n)。

所以把mu[]求出来,枚举n就行了,其中mu[i]为i的莫比乌斯函数。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<cstring>
 4 #include<cstdlib>
 5 using namespace std;
 6 const int N = 1e5+1;
 7
 8 int vis[N];
 9 int mu[N];
10 int prime[N],cnt;
11 int date[N];
12 long long ys[N];
13 int num[N];
14 void init()
15 {
16     memset(vis,0,sizeof(vis));
17     mu[1] = 1;
18     cnt = 0;
19     for(int i=2;i<N;i++)
20     {
21         if(!vis[i])
22         {
23             prime[cnt++] = i;
24             mu[i] = -1;
25         }
26         for(int j = 0;j<cnt&&i*prime[j]<N;j++)
27         {
28             vis[i*prime[j]] = 1;
29             if(i%prime[j]) mu[i*prime[j]] = -mu[i];
30             else
31             {
32                 mu [i *prime[j]] = 0;
33                 break;
34             }
35         }
36     }
37 }
38 int main()
39 {
40     int n,maxn;
41     init();
42     while(scanf("%d",&n)>0)
43     {
44         memset(num,0,sizeof(num));
45         memset(ys,0,sizeof(ys));
46         maxn = -1;
47         for(int i=1;i<=n;i++){
48             scanf("%d",&date[i]);
49             num[date[i]] ++;
50             if(date[i]>maxn) maxn = date[i];
51         }
52         /***计算F(N)*/
53         for(int i=1;i<=maxn;i++)
54         {
55             for(int j=i;j<=maxn;j=j+i)
56             {
57                 ys[i] = ys[i] + num[j];
58             }
59         }
60         long long sum = 0;
61         for(int i=1;i<=maxn;i++){
62             long long tmp = (long long)ys[i] *( ys[i]-1 )/2;
63              sum = sum + mu[i]*tmp;
64         }
65
66         printf("%I64d\n",sum);
67     }
68     return 0;
69 }

nyoj CO-PRIME 莫比乌斯反演,布布扣,bubuko.com

时间: 2024-08-09 02:18:02

nyoj CO-PRIME 莫比乌斯反演的相关文章

【XSY2719】prime 莫比乌斯反演

题目描述 设\(f(i)\)为\(i\)的不同的质因子个数,求\(\sum_{i=1}^n2^{f(i)}\) \(n\leq{10}^{12}\) 题解 考虑\(2^{f(i)}\)的意义:有\(f(i)\)总因子,每种可以分给两个人中的一个.那么就有\(2^{f(i)}=\sum_{d|i}[\gcd(d,\frac{i}{d})=1]\) 然后就是简单莫比乌斯反演了. \[ \begin{align} s&=\sum_{i=1}^n\sum_{d|i}[\gcd(d,\frac{i}{d}

bzoj 2820 / SPOJ PGCD 莫比乌斯反演

那啥bzoj2818也是一样的,突然想起来好像拿来当周赛的练习题过,用欧拉函数写掉的. 求$(i,j)=prime$对数 \begin{eqnarray*}\sum_{i=1}^{n}\sum_{j=1}^{m}[(i,j)=p]&=&\sum_{p=2}^{min(n,m)}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{p}\rfloor}[i⊥j]\newline&=&\sum_{p=

hdu1695(莫比乌斯反演)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意: 对于 a, b, c, d, k . 有 x 属于 [a, b],  y 属于 [c, d], 求 gcd(x, y) = k 的 x, y 的对数 . 其中 a = b = 1 . 注意: (x, y), (y, x) 算一种情况 . 思路: 莫比乌斯反演 可以参考一下: http://blog.csdn.net/lixuepeng_001/article/details/5057

bzoj2301 [HAOI2011]Problem b【莫比乌斯反演 分块】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2301 很好的一道题.首先把每个询问转化为4个子询问,最后的结果就是这四个子询问的记过加加减减,类似二维前缀和.那么问题转化为在1 <= x <= lmtx, 1 <= y <= lmty时gcd(x, y) == k的对数,这个问题在转化一下,转化成1 <= x <= lmtx / k,1 <= y <= lmty / k时x与y互质的对数.莫比乌斯反

BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演

分析:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 然后对于求这样单个的gcd(x,y)=k的,我们通常采用莫比乌斯反演 但是,时间复杂度是O(n*(n/k))的,当复杂度很坏的时候,当k=1时,退化到O(n^2),超时 然后进行分块优化,时间复杂度是O(n*sqrt(n)) #include<cstdio> #include<cstring> #include<queue

ACdream 1114(莫比乌斯反演)

传送门:Number theory 题意:给n个数,n 和 每个数的范围都是 1---222222,求n个数中互质的对数. 分析:处理出每个数倍数的个数cnt[i],然后进行莫比乌斯反演,只不过这里的F(i)=cnt[i]*(cnt[i]-1)/2. #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include <cstring> #include <st

ACdream 1148(莫比乌斯反演+分块)

传送门:GCD SUM 题意:给出N,M执行如下程序:long long  ans = 0,ansx = 0,ansy = 0;for(int i = 1; i <= N; i ++)   for(int j = 1; j <= M; j ++)       if(gcd(i,j) == 1) ans ++,ansx += i,ansy += j;cout << ans << " " << ansx << " &qu

bzoj 2301 莫比乌斯反演

求$(i,j)=k$的一系列模板题之一. 但是这里i,j是有下界的,注意用容斥去掉重复组,其他都一样了. /** @Date : 2017-09-09 19:21:18 * @FileName: bzoj 2301 莫比乌斯反演 多组 范围内 GCD=k.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : $Id$ */ #inclu

bzoj 1101 [POI2007]Zap - 莫比乌斯反演

Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a ,y<=b,并且gcd(x,y)=d.作为FGD的同学,FGD希望得到你的帮助. Input 第一行包含一个正整数n,表示一共有n组询问.(1<=n<= 50000)接下来n行,每行表示一个询问,每行三个 正整数,分别为a,b,d.(1<=d<=a,b<=50000) Output 对于每组询问,输出到输出文件zap.out一个正