Uva10820 欧拉公式模板(求小于n且与n互素的数的个数)

题意:

给出n,算出小于等于n的所有数中,有几对互质;

解法:

本质就是求有多少个2元组(x,y)满足:1 <= x,y <= n,且x与y互素。

除了(1,1)之外,其他所有的x和y都不相同,我们设x<y的二元组有f(n)个,答案就是2f(n)+1 f(n)=phi(2)+phi(3)+...+phi(n);

 1 #include<cstdio>
 2 #include<cmath>
 3 using namespace std;
 4 const int maxn = 5e4 + 5;
 5 int phi[maxn];
 6
 7 //欧拉函数,求小于n且与n互素的整数个数
 8 int euler_phi(int n) {
 9     int m = (int)sqrt(n + 0.5);
10     int ans = n;
11     for (int i = 2; i <= m; i++) if (n%i == 0) {
12         ans = ans / i*(i - 1);
13         while (n%i == 0)n /= i;
14     }
15     if (n > 1)ans = ans / n*(n - 1);
16     return ans;
17 }
18
19 //求小于n的所有数的欧拉函数值
20 void phi_table(int n, int *phi) {
21     for (int i = 2; i <= n; i++)phi[i] = 0;
22     phi[1] = 1;
23     for (int i = 2; i <= n; i++)if (!phi[i])
24         for (int j = i; j <= n; j += i) {
25             if (!phi[j])phi[j] = j;
26             phi[j] = phi[j] / i*(i - 1);
27         }
28 }
29
30 int main() {
31     int n;
32     while (scanf("%d", &n) && n) {
33         phi_table(n, phi);
34         int ans = 0;
35         for (int i = 2; i <= n; i++) ans += phi[i];
36         printf("%d\n", ans + ans + 1);
37     }
38     return 0;
39 }

原文地址:https://www.cnblogs.com/romaLzhih/p/9499461.html

时间: 2024-07-29 16:15:03

Uva10820 欧拉公式模板(求小于n且与n互素的数的个数)的相关文章

2017乌鲁木齐区域赛K(容斥原理【求指定区间内与n互素的数的个数】)

#include<bits/stdc++.h>using namespace std;const long long mod = 998244353;typedef const long long ll;vector<long long>p;long long inv(long long x,long long y)//快速幂求逆元模板(以乘代除){    long long r=1;    while(y>0)    {        if(y&1)        

HDU4135 (求a~b内与n互素的数的个数) 容斥原理

掌握了容斥原理后,便会发现,这是一道简单的容斥原理的题. 题目描述:给定A, B, N (1 <= A <= B <= 10^15,1<=N <= 10^9).求[A,B]区间内与N互素的数的个数 步骤: (1)将问题化为求1~B,1~A中与N互素的数的个数的差,当然考虑到A可能与N互素的情况,在实际操作时, 即求1~A时最好改成求1~A-1(包含A-1): (2)求N的质因子(可参考:http://blog.csdn.net/yzj577/article/details/3

第十六周oj刷题——Problem K: 填空题:类模板---求数组的最大值

Description 类模板---求数组的最大值 找出一个数组中的元素的最大值,数组大小为10.(用类模板来实现) 数组元素类型作为类模板的参数. Input 10个int型数据 10个double型数据 10个char型数据 10gestring型数据 Output 10个int型数据的最大值 10个double型数据的最大值 10个char型数据的最大值 10个string型数据的最大值 Sample Input 1 3 5 7 9 8 6 4 2 0 1.2 3.4 5.66 7.8 9

OJ刷题之《函数模板--求n个数之和》

题目描述 利用函数模板求4个数的和. 部分代码已给定如下,只需要提交缺失的代码. #include <iostream> using namespace std; /* 补充缺少代码 */ int main() { double result; unsigned char c1,c2,c3,c4; cin>>c1>>c2>>c3>>c4; result = sum<unsigned char>(c1,c2,c3,c4); cout&l

背包算法练习--求小于某数字的数组最大和:

////背包算法练习--求小于某数字的数组最大和: var bestS = {val:0,str:""}; var LIMIT ; Array.prototype.sum = function(){ var s = 0; for(var i = 0;i < this.length;i++){ s+= this[i]; } return s; } function f(bagArr){ var arrS = bagArr.sum(); if(arrS < LIMIT){ be

求小于10000的素数的个数 Exercise06_10

1 /** 2 * @author 冰樱梦 3 * 时间:2018年下半年 4 * 题目:求小于10000的素数的个数 5 * 6 */ 7 public class Exercise06_10 { 8 public static void main(String[] args){ 9 int sum=0; 10 for(int i=1;i<=1000;i++){ 11 if(isPrime(i))sum++; 12 } 13 System.out.println("1000以内素数的个数

一个简单的公式——求小于N且与N互质的数的和

首先看一个简单的东西. 若gcd(i,n)=1,则有gcd(n-i,n)=1. 于是在小于N且与N互质的数中,i与n-i总是成对存在,且相加等于n. 考虑i=n-i的特殊情况,此时n=2*i,由gcd(i,n)=1,得n=2.此时手动计算ans=1. 因为小于N且与N互质的数的个数为φ(n),于是我们可以得出公式ans=n*φ(n)/2.

求 区间[a,b]内满足p^k*q*^m(k&gt;m)的数的个数

题目描述: 1<=a,b<=10^18,p,q都是素数  2<=p,q<=10^9; 求在[a,b]内可以表示为  x*p^k*q^m  k > m   的数的个数 分析: 由于要小于b,因此m一定小于 log10(b)/log10(p*q); 因此我们可以枚举m,中间计数的时候需要用到容斥. 具体看代码: #include <iostream> #include <cstdio> #include <cmath> #include <

分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)

思路: 分治法 归并排序的过程中,有一步是从左右两个数组中,每次都取出小的那个元素放到tmp[]数组中 右边的数组其实就是原数组中位于右侧的元素.当不取左侧的元素而取右侧的元素时,说明左侧剩下的元素均比右侧的第一个元素大,即均能构成一个逆序对.假设现在左侧剩余n个元素,则逆序对数+n. 另外,如果当所有右侧的元素都取完,但是左侧仍然有元素剩余时,左侧剩余的元素已经在之前的运算中加到了逆序对中,不需要再添加一次 下面给出 归并排序 和 求逆序对数 两份代码: code1: 归并排序 #includ