题解:艾米利亚的施法

题目:http://cojs.tk/cogs/problem/problem.php?pid=2432

题解:




代码如下:

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 10000000;
template<class T>inline void read(T &x) {
	x = 0; bool flag = 0; char ch = getchar();
	while(ch<'0'||ch>'9'){ if(ch == '-') flag = 1; ch = getchar(); }
	while(ch>='0'&&ch<='9'){ x = x * 10 + ch - '0'; ch = getchar(); }
	if(flag) x = -x;
}
ll  f[maxn+10],prime[maxn+10],tot = 0;
bool check[maxn+10];
inline void get_f() {
	f[1] = 1; tot = 0; int cnt = 0,x = 0,tmp = 0,p = 0;
	for(int i = 2;i <= maxn;++ i) { 
		if(!check[i]) {
			prime[tot ++] = i; f[i] = i - 2;
		} 
		for(int j = 0;j < tot;++ j) {
			if(i * prime[j] > maxn)  break;
			check[i * prime[j]] = true;
			if(i % prime[j]) {
				f[i * prime[j]] = f[i] * (prime[j] - 2);
			} else {
				cnt = 0; x = i; tmp = 1; p = prime[j];
				while(x % p == 0) { x /= p; cnt ++; tmp *= p;}
				if(cnt == 1) {
					f[i * p] = f[i / p] * (p - 1) * (p - 1);
				} else {
					f[i * p] = f[i] * p; 
				}
				break;
			}
		}
	}
	for(int i = 2;i <= maxn;++ i) f[i] += f[i-1];
}
int n = 0,m = 0;
int main() {
	freopen("aimiliyausemagic.in","r",stdin);
	freopen("aimiliyausemagic.out","w",stdout);
	get_f();
	int T = 0; read(T);
	while(T --) {
		read(n); read(m);
		if(n > m) swap(n,m);
		ll ans = 0;
		for(int i = 1,last = 0;i <= n;i = last+1) {
			last = min(n/(n/i),m/(m/i));
			ans += (ll)(f[last]-f[i-1])*(n/i)*(m/i);
		}
		printf("%lld\n",ans);
	}
	fclose(stdin);fclose(stdout);
	return 0;
}



posted @ 2016-08-13 16:53  Sky_miner  阅读(167)  评论(0编辑  收藏  举报