bzoj 2818 gcd 线性欧拉函数

2818: Gcd

Time Limit: 10 Sec  Memory Limit: 256 MB
[Submit][Status][Discuss]

Description

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.

Input

一个整数N

Output

如题

Sample Input

4

Sample Output

4

HINT

hint

对于样例(2,2),(2,4),(3,3),(4,2)

1<=N<=10^7

思路:gcd(x,y)=p;p为素数;

   gcd(x/p,y/p)==1;

   一个p的贡献为1-(N/p),求前缀和意思;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000009
#define inf 999999999
#define esp 0.00000000001
//#pragma comment(linker, "/STACK:102400000,102400000")
const int N=1e5,M=1e7+1000;
ll p[M],ji;
bool vis[M];
ll phi[M];
void get_eular(int n)
{
    ji = 0;
    memset(vis, true, sizeof(vis));
    for(int i = 2; i <= n; i++)
    {
        if(vis[i])
        {
            p[ji ++] = i;
            phi[i] = i - 1;
        }
        for(int j = 0; j < ji && i * p[j] <= n; j++)
        {
            vis[i * p[j]] = false;
            if(i % p[j] == 0)
            {
                phi[i * p[j]] = phi[i] * p[j];
                break;
            }
            else
            phi[i * p[j]] = phi[i] * phi[p[j]];
        }
    }
}
ll sumphi[M];
int main()
{
    ll x,y,z,i,t;
    get_eular(10000100);
    sumphi[0]=1;
    for(i=1;i<=10000000;i++)
    sumphi[i]=sumphi[i-1]+phi[i];
    while(~scanf("%lld",&x))
    {
        ll ans=0;
        for(i=0;p[i]<=x;i++)
        ans+=2*sumphi[x/p[i]]-1;
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-10-05 14:41:33

bzoj 2818 gcd 线性欧拉函数的相关文章

bzoj 2818 GCD 数论 欧拉函数

bzoj[2818]Gcd Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sample Output 4 HINT hint对于样例(2,2),(2,4),(3,3),(4,2) 1<=N<=10^7 题解一(自己yy) phi[i]表示与x互质的数的个数 即gcd(x,y)=1 1<=y<x ∴对于x,y 若a为素数 则gcd(xa,

BZOJ 2818 Gcd 线性欧拉筛(Eratosthenes筛)

题目大意:给定整数N(N <= 1e7),求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.. 思路:推一推. 设gcd(x,y) = p,则x / p与y / p互质 问题就转化成了N / p中有多少个数互质,然后累加就可以了. =>对于任意a,b,a <= N / p,b <= N / p,且a与b互质 =>gcd(a,b) == 1 现在问题就很明显了,看到这个形式就很容易想到欧拉函数,求一下phi,算一下前缀和,累加. 注意这里求欧拉一

BZOJ 2818 Gcd 线性欧拉

题意:链接 方法:线性欧拉 解析: 首先列一下表达式 gcd(x,y)=z(z是素数并且x,y<=n). 然后我们可以得到什么呢? gcd(x/z,y/z)=1; 不妨令y>=x 则可以得到我们要的答案就是∑max(y/z)i=1phi(i) 而max(y/z)就是max(n/z): 所以只需要枚举一下质数z随便搞一下就好了,最好用前缀和记录 HINT:前缀和写树状数组的都是(*) 代码: 正常人做法1.1s #include <cstdio> #include <cstri

bzoj 2818 Gcd 【欧拉函数】

问题:求gcd(x,y)==质数, 1<=x,y<=n的有多少对? 做这题的时候,懂得了一个非常重要的转化:求(x, y) = k, 1 <= x, y <= n的对数等于求(x, y) = 1, 1 <= x, y <= n/k的对数!所以,枚举每个质数p,然后求(x, y) = 1, 1 <= x, y <= n/p的个数. (x, y) = 1 的个数如何求呢?欧拉函数! #include <stdio.h> #include <io

bzoj 2818 Gcd(欧拉函数)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2818 [题意] 问(x,y)为质数的有序点对的数目. [思路] 定义f[i]表示i之前(x,y)=1的有序点对的数目,则有递推式: f[1]=1 f[i]=f[i-1]+phi[i]*2 我们依次枚举小于n的所有素数,对于素数t,(x,y)=t的数目等于(x/t,y/t),即f[n/t]. [代码] 1 #include<cstdio> 2 #include<cstring&

【BZOJ】2818: Gcd(欧拉函数/莫比乌斯)

http://www.lydsy.com/JudgeOnline/problem.php?id=2818 我很sb的丢了原来做的一题上去.. 其实这题可以更简单.. 设 $$f[i]=1+2 \times \phi (i) $$ 那么答案就是 $$\sum_{p是质数} f[n/p]$$ 就丢原来的题了...不写了.. #include <cstdio> #include <cstring> #include <cmath> #include <string>

uva 11317 - GCD+LCM(欧拉函数+log)

题目链接:uva 11317 - GCD+LCM 题目大意:给定n,求出1~n里面两两的最大公约的积GCD和最小公倍数的积LCM,在10100进制下的位数. 解题思路:在n的情况下,对于最大公约数为i的情况又phi[n/i]次.求LCM就用两两乘积除以GCD即可. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; ty

BZOJ2818 GCD 【欧拉函数,线性筛】

题目大意: 给一个范围[1,n],从中找出两个数x,y,使得gcd(x,y)为质数,问有多少对(x,y有序) 解法: 不难,欧拉函数练手题,可以定义集合P ={x|x为素数},那么我们枚举gcd(x,y)可能等于的情况,对于任意p∈P可以得到:gcd(k1·p,k2·p) = p,当且仅当gcd(k1,k2) =1;那么我们就只需要枚举所有的k1,k2了.不妨设k1>k2,那么给定k1,k2的个数就是phi(k1),因为有序,所以给phi*2,但是,这样是否漏算了呢?没错,漏算了(1,1),补上

(hdu step 7.2.2)GCD Again(欧拉函数的简单应用——求[1,n)中与n不互质的元素的个数)

题目: GCD Again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 125 Accepted Submission(s): 84   Problem Description Do you have spent some time to think and try to solve those unsolved problem afte