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

Posted 吾之奉先

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于UVA 11426 (欧拉函数&&递推)的主要内容,如果未能解决你的问题,请参考以下文章

GCD - Extreme (II) UVA - 11426(欧拉函数!!)

UVA - 11426 GCD - Extreme (II) (欧拉函数)

UVA11426

UVA - 10820欧拉函数的应用

UVa 11440 - Help Tomisu(欧拉函数 + 问题转换)

UVa 10735 - Euler Circuit(最大流 + 欧拉回路)