bzoj2818 Gcd

Description

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

1<=x,y<=N且Gcd(x,y)为质数等价于Gcd(x/p,y/p)=1,p为质数,

线性筛求1~n的欧拉函数值和质数表,

对欧拉函数求前缀和,枚举质数计算x/p<y/p的情况,结果乘二(加上x/p>y/p的情况),

最后加上x=y=p的情况

#include <cstdio>
bool isnp[10000001]={1,1};
int N=10000000,phi[10000001]={0,0};
int ps[1000000],p=0;
int n=0;
long long as[10000001],ans=0;
int main(){
    int i;
    scanf("%d",&n);
    for(i=2;i<=n;i++){
        if(!isnp[i])ps[p++]=i,phi[i]=i-1;
        for(int j=0;j<p&&i*ps[j]<=N;j++){
            isnp[i*ps[j]]=1;
            if(i%ps[j])phi[i*ps[j]]=phi[i]*(ps[j]-1);
            else{
                phi[i*ps[j]]=phi[i]*ps[j];
                break;
            }
        }
    }
    for(i=1;i<=n;i++)as[i]=as[i-1]+phi[i];
    for(i=0;i<p&&ps[i]<=n;i++)ans+=as[n/ps[i]];
    printf("%lld",ans+ans+i);
    return 0;
}
时间: 2024-12-15 13:31:42

bzoj2818 Gcd的相关文章

素数筛&amp;&amp;欧拉筛 BZOJ2818 Gcd BZOJ2190 [SDOI2008]仪仗队

折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体的解释看的迷迷糊糊,特别是欧拉函数的求解 http://blog.csdn.net/lerenceray/article/details/12420725 代码如下 1 void ES(){ 2 for(int i=2;i<n;i++){ 3 if (!pd[i]){ 4 prime[++top]=

BZOJ2818 Gcd 欧拉函数

题意:给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 题解:我们枚举素数p,后面的过程和BZOJ2705一样,不同的是我们限制x>=y,假定得到的答案是ans,那么实际上答案是2*ans-1(加上x<=y,x==y重复计算了) #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <

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),补上

【数论】【筛法求素数】【欧拉函数】bzoj2818 Gcd

gcd(x,y)(1<=x,y<=n)为素数(暂且把(x,y)和(y,x)算一种) 的个数 <=> gcd(x/k,y/k)=1,k是x的质因数 的个数 <=> Σφ(x/k) (1<=x<=n,k是x的质因子) 这样的复杂度无法接受, ∴我们可以考虑枚举k,计算Σφ(q/k) (k是n以内的质数,q是n以内k的倍数),即Σ[φ(1)+φ(2)+φ(3)+...+φ(p)] (p=n/k) 介个phi的前缀和可以预处理粗来. 但是(x,y)和(y,x)并不同

Bzoj2818 Gcd(莫比乌斯反演)

题面 题意都在题目里面了 题解 你可以把题意看成这个东西 $$ \sum_{i=1}^n\sum_{j=1}^m\mathbf f(gcd(i,j)) $$ 其中$\mathbf f(n)$为$是否是一个质数[n是否是一个质数]$ 然后把$\mathbf f$反演一下,找到一个$\mathbf g$令$\mathbf f=\mathbf 1 \ast \mathbf g$,即: $$ \mathbf g(n)=\sum_{d\mid n}\mu(\frac nd)\cdot \mathbf f(

[BZOJ2818] Gcd (数论,欧拉函数,线性筛)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818 必须用线性筛. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 10001001; 5 LL phi[maxn], sum[maxn], n; 6 bool isprime[maxn]; 7 LL prime[maxn]; 8 int tot;

【枚举】【莫比乌斯反演】【线性筛】bzoj2818 Gcd

思路是hdu6134的简化版,只需要在外面套上一个枚举素数就行了. http://www.cnblogs.com/autsky-jadek/p/7491730.html #include<cstdio> using namespace std; #define N 10000000 bool notpri[N+5]; int pri[N+5],mu[N+5],sum[N+5]; typedef long long ll; void shai_mu() { notpri[1]=1; mu[1]=

BZOJ2818: Gcd 莫比乌斯反演

分析:筛素数,然后枚举,莫比乌斯反演,然后关键就是分块加速(分块加速在上一篇文章) #include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namespace std; typedef long long LL; const

(转载)关于gcd的8题

发现其实有关gcd的题目还是挺多的,这里根据做题顺序写出8题. [bzoj2818: 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的个数.