UVA 11426 (欧拉函数&&递推)

题意:给你一个数N,求N以内和N的最大公约数的和

解题思路:

一开始直接想暴力做,4000000的数据量肯定超时。之后学习了一些新的操作。

题目中所要我们求的是N内gcd之和,设s[n]=s[n-1]+gcd(1,n)+gcd(2,n)+gcd(3,n)+gcd(4,n).......

再设f[n]=gcd(1,n)+gcd(2,n)+gcd(3,n)+gcd(4,n).......;

思考一下,假设gcd(x,n)=ans,ans便是x和n的最大公约数,那么有几个ans我们将某ans的个数sum(num*ans)是不是就是当前f[n]的值;

那么某个ans的个数num我们该怎么求???

gcd(x,n)=ans;那么gcd(x/ans,n/ans)就是1;就是说x/ans和n/ans是互素的,那么求n以内和n互素的数的个数我们怎么办???就用欧拉函数phi;

其个数就是phi[n/ans];

然后,,,,你以为求这点就做完了是吗??玩笑,,,;

你可以直接打出4000 000欧拉表,那么我们该怎么遍历赋值f[n];f[n]=num*ans;我们遍历n在遍历ans么??这个不现实,在当前这个n中会有部分ans白白计算

所以我们最好的办法就是先行枚举ans,我们知道,当前ans所对应的n一定是ans的倍数,所以我们遍历n极为方便,只需要令n=2*ans,3*ans,4*ans,5*ans......

这里有个点就是n不能是ans,所以我们第二重循环里就应该从2*ans开始;这个地方一会在代码中点出;

具体就是这么多;

AC代码

 1 #include<stack>
 2 #include<queue>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<algorithm>
 8
 9 using namespace std;
10
11 #define INF 0x3f3f3f3f
12 typedef long long ll;
13 const ll maxn = 4000005;
14 ll n;
15
16 ll euler[maxn];
17 ll fun_[maxn];
18
19 void euler_(ll maxn)
20 {
21     for (int i=1;i<=maxn;i++)
22     {
23         euler[i]=i;
24     }
25     for (int i=2;i<maxn;i++)
26     {
27         if (euler[i]==i)
28         {
29             for (int j=i;j<maxn;j+=i)
30             {
31                 euler[j]=euler[j]/i*(i-1);
32                // cout<<euler[j]<<endl;
33             }
34         }
35     }
36 }
37
38 ll s[maxn];
39
40
41 int main()
42 {
43     euler_(maxn);
44     //memset(fun_,0,sizeof(fun_));
45     for (int i=1;i<=maxn;i++)
46     {
47         for (int j=i+i;j<=maxn;j+=i)
48         {
49             //cout<<i<<" "<<n/i<<" "<<euler[n/i]<<endl;
50
51             fun_[j]+=i*euler[j/i];
52             //cout<<fun_[j]<<endl;
53         }
54     }
55     s[1]=0;
56
57     for (int i=2;i<=maxn;i++)
58     {
59         s[i]=s[i-1]+fun_[i];
60         //cout<<i<<" "<<s[i]<<endl;
61     }//cout<<"***********"<<endl;
62     while (cin>>n&&n)
63     {
64         //cout<<n<<endl;
65         cout<<s[n]<<endl;
66     }
67 }
时间: 2024-07-30 06:12:55

UVA 11426 (欧拉函数&&递推)的相关文章

UVa 11426 (欧拉函数 GCD之和) GCD - Extreme (II)

题意: 求sum{gcd(i, j) | 1 ≤ i < j ≤ n} 分析: 有这样一个很有用的结论:gcd(x, n) = i的充要条件是gcd(x/i, n/i) = 1,因此满足条件的x有phi(n/i)个,其中Phi为欧拉函数. 所以枚举i和i的倍数n,累加i * phi(n/i)即可. 1 #include <cstdio> 2 typedef long long LL; 3 4 const int maxn = 4000000; 5 6 int phi[maxn + 10]

BZOJ 3884(上帝与集合的正确用法-欧拉函数递推找极限)[Template:数论 V2]

3884: 上帝与集合的正确用法 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 523  Solved: 237 [Submit][Status][Discuss] Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做"元". 第二天, 上帝创造了一个新的元素,称作"α"."α"被定义为"元"构成的集合.容

BNU 12846 LCM Extreme 最小公倍数之和(线性欧拉筛选+递推)

LCM Extreme Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 596464-bit integer IO format: %lld      Java class name: Main Find the result of the following code:unsigned long long allPairLcm(int n){ unsig

UVa 11440 (欧拉函数) Help Tomisu

题意: 给出N和M,统计区间x ∈ [2, N!],x满足所有素因子都大于M的x的个数. 分析: 首先将问题转化一下,所有素因子都大于M 等价于 这个数与M!互素 对于k大于M!,k与M!互素等价于 k % M! 与 M!互素 所以我们可以求出φ(M!)(φ为欧拉函数) 然后乘以N! / M!,最后答案再减一(因为是从2开始统计的) 欧拉函数的公式为a phifac[n] = φ(n!),我们递推求phifac 当n为合数时,n!和(n-1)!的素因数的集合是一样的,所以phifac[n] =

UVA - 10820欧拉函数的应用

这是一道很基础的欧拉函数的题目 题意要求  (x,y) 互质 &&x<=n&&y<=n 求互质对数 可以运用容斥,求出 phi(n)=n(1-1/n1)(1-1/n2)......(1-1/nk); 因为(2,4) (4,2) 算两对,所以 答案为 2*f(n)+1; #include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream>

UVa 10837 (欧拉函数 搜索) A Research Problem

发现自己搜索真的很弱,也许做题太少了吧.代码大部分是参考别人的,=_=|| 题意: 给出一个phi(n),求最小的n 分析: 回顾一下欧拉函数的公式:,注意这里的Pi是互不相同的素数,所以后面搜索的时候要进行标记. 先找出所有的素数p,满足(p - 1)整除题目中所给的phi(n) 然后暴搜.. 素数打表打到1e4就够了,如果最后剩下一个大素数单独进行判断. 1 #include <cstdio> 2 #include <cmath> 3 #include <cstring&

A Research Problem UVA - 10837 欧拉函数逆应用

平时看到的题目是给n求phi(n) 现在是给phi(n)求一个最小n 当一个数为素数是m=n*(1-1/n); 例如 12=13(1-1/13);所以可以得出 m%(n-1)==0 时,n-1为n的素因子 m=n*(1-1/p1)*(1-1/pn); n=p1^x1*(p1-1)*p2^x2(p2-1)......; #include <iostream> #include <stdio.h> #include <cmath> #include <algorith

POJ 3090 ZOJ 2777 UVALive 3571 Visible Lattice Points(用递推比用欧拉函数更好)

题目: Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin, is visible from the origin if the line from (0, 0) to (x, y) does not pass through any other lattice point. For exa

UVa 11426 GCD - Extreme (II) (欧拉函数应用&#183;O(N*logN))

题意  令  G(n) = sum{gcd(i, j) | 0 < i < n, i < j <= n}  给你一个n  输出G(n) 令 F(n) = sum{gcd(i, n) | 0 < i < n}  那么有递推式 G(n) = G(n-1) + F(n) , G(0)  = 0  也就是说只用求出F(n) 就能递推求出 G(n)了  而求F(n)就比较容易了 对于i  设 x < i , gcd(x,i) = 1 即x, n 互质 则  gcd(2*x,