lightoj 1375
题目大意:
求小于
n
的数字中,任意两个不相等的数字的
思路:
lcm(1,2)
lcm(1,3)
lcm(1,4)
…
lcm(1,n)
lcm(2,3)
lcm(2,4)
…
lcm(2,n)
lcm(3,4)
…
lcm(3,n)
…
lcm(n−1,n)
即可求
∑i=2n∑j=1j=i−1lcm(j,i)
;
lcm(i,n)=i∗ngcd(i,n)
, 令
gcd(i,n)=G;
lcm(i,n)=ig∗ng∗g;
gcd(ig,ng)=1
;
又已知小于
n
且与
∑i=1n−1lcm(i,n)=ig∗φ(ng)2∗g
;
即:
∑i=1n−1lcm(i,n)=∑d∣n,d≠nd∗φ(d)2∗n
; 即枚举n的因子;
取模
264
, 变量定义为
unsigned
long
long
; 溢出
264
即为取模
264
;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#define N 3000001
#define LL unsigned long long
using namespace std;
int euler[N];
LL f[N], a[N];
void init_Euler()
{
euler[1] = 1;
for (int i = 2; i < N; i++)
{
euler[i] = i;
}
for (int i = 2; i < N; i++)
{
if (euler[i] == i)
{
for (int j = i; j < N; j += i)
{
euler[j] = euler[j] / i * (i - 1);
}
}
}
memset(a, 0, sizeof(a));
memset(f, 0, sizeof(f));
for(int i = 2; i < N; i++)
{
for(int j = i; j < N; j += i)
{
f[j] += ((LL)euler[i]) * i / 2 * j;
}
a[i] = a[i - 1] + f[i];
}
}
int main()
{
init_Euler();
int T;
scanf("%d", &T);
for (int cas = 1; cas <= T; cas++)
{
int n;
scanf("%d", &n);
printf("Case %d: %llu\n", cas, a[n]);
}
return 0;
}