BZOJ2226

題意大概是:給定一個N,求出sigma(lcm(i,n))其中(1<=i<=n)

推波式子:

然後這個我們可以O(N)預處理歐拉函數,然後每次詢問根號N,當然這題是存在詢問O(1)的算法,有興趣的讀者可以思考。

附上代碼:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXX = 1000005;
int n, N = MAXX - 5, i, j, cnt, prim[MAXX], phi[MAXX], T;
long long ans;
bool f[MAXX];
inline int get()
{
	char c;
	while ((c = getchar()) < 48 || c > 57);
	int res = c - 48;
	while ((c = getchar()) >= 48 && c <= 57)
	res = res * 10 + c - 48;
	return res;
}
int main()
{
	phi[1] = 1;
	for(i = 2; i <= N; i ++)
	{
		if (!f[i])
		{
			phi[i] = i - 1;
			prim[++cnt] = i;
		}
		for(j = 1; j <= cnt && i * prim[j] <= N; j ++)
		{
			f[prim[j] * i] = 1;
			if (i % prim[j]) phi[i * prim[j]] = phi[i] * (prim[j] - 1);
			else {phi[i * prim[j]] = phi[i] * prim[j]; break;}
		}
	}
	cin >> T;
	for(i = 1; i <= T; i ++)
	{
		n = get();
		ans = 1;
		int nn = sqrt(n);
		for(j = 2; j <= nn; j ++)
		if (!(n % j))
		{
			int ot = n / j;
			ans += (phi[j] * (long long)j) >> 1;
			if (ot != j) ans += (phi[ot] * (long long)ot) >> 1;
		}
		ans += (phi[n] * (long long)n) >> 1;
		printf("%lld\n", ans * n);
	}
}


發佈了44 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章