您的位置:首页 > 其它

《算法竞赛-训练指南》第二章-2.9_UVa 11426

2013-08-13 16:11 288 查看
题目越来越难,自己做都做不下去了,主要是自己不能够静下心来。这怎么静下心呀?

和一些人还是差距太大呀。人家才是真正的聪明人,我这一遇到难点就做不下去了,这怎么可能能做出什么成绩,每次都当在后悔的时候自己才下定决心,那样真的有用么?

而自己学习这些知识的最终目的又是什么呢?这真是个矛盾的地方。

自己明明已经告诫自己了,自己不适合那种势力的想法,我就是单纯的想学习知识。学到学不到,全凭自己的兴趣,自己爱它,所以愿意将全部的时间都用在这上面,而如果自己一旦将之当做包袱,或者找到了更好的自己的兴趣点,这,自己就只能放弃了。

而且,一定要注意自己的自制力,自制力不行,就在自己幡然悔悟的时候即使将所有的条件都断掉,然后逼自己。不逼自己是不行的。肯定不行的。

不和别人比,你只和自己比,只和自己的生活比,不拿什么当包袱,只拿自己的生活当包袱,自己要走的路还有很长,自己的状态,姿态是最重要的。

不是不求胜,只是比自己。

说一下这道题目的意思:题目是求gcd的和。范围是两重1-N。这要是暴力的话肯定不行。毕竟是400W的数据量,但是技巧,好像自己还真是不知道。题解给出了思想。令g(i,n)表示1<i<=n的gcd(i,n)的和,那么这些gcd的和就包含了gcd(i,n) = x,而x是n的约数,而,还有一个公式就是gcd(i/x, n/x)=1,这样一来,就和欧拉函数挂上勾了。

有了这个思想别的也就简单多了。

贴出代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;

const int MAXN = 4000000 + 11;

typedef long long LL;

LL phi[MAXN];

LL f[MAXN];

LL S[MAXN];

void init()
{
memset(phi, 0, sizeof(phi));
phi[1] = 1;
for (int i = 2; i < MAXN; i++)
{
if (phi[i] == 0)
{
for (int j = i; j < MAXN; j += i)
{
if (phi[j] == 0)
{
phi[j] = j;
}
phi[j] = phi[j] / i * (i - 1);
}
}
}
memset(f, 0, sizeof(f));
for (int i = 1; i < MAXN; i++)
{
for (int j = i * 2; j < MAXN; j += i)
{
f[j] += i * phi[j / i];
}
}
S[2] = f[2];
for (int i = 3; i < MAXN; i++)
{
S[i] = S[i - 1] + f[i];
}
}

int main()
{
int N;
init();
while (scanf("%d", &N) != EOF)
{
if (N == 0)
{
break;
}
printf("%lld\n", S
);

}
// system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: