SPOJ - GCDEX GCD Extreme 题解

题意:
有q此询问每次询问一个N,求G的值。

G = 0;
for (i = 1; i < N; i++)
  for (j = i+1; j <= N; j++) 
    G += gcd(i, j);

首先N的范围很小一看就知道是预处理询问。
a n s w e r i answer_i answeri表示N=i时的答案。 a n s w e r i = a n s w e r i − 1 + ∑ j = 1 i − 1 g c d ( j , i ) answer_i=answer_{i-1}+\sum_{j=1}^{i-1} gcd(j,i) answeri=answeri1+j=1i1gcd(j,i)
这时就是需要求对于一个i,求出 ∑ j = 1 i − 1 g c d ( j , i ) \sum_{j=1}^{i-1} gcd(j,i) j=1i1gcd(j,i)可以发现gcd(j,i)时i的一个因子,所以只需要枚举i的因子g。然后就是在 [ 1 , i − 1 ] [1,i-1] [1,i1]中,有多少j满足 g ∣ j , g c d ( j g , j g ) = 1 g|j,gcd(\frac{j}{g},\frac{j}{g})=1 gj,gcd(gj,gj)=1也就是和 j g \frac{j}{g} gj互质的数的个数,显然这就是 ϕ \phi ϕ的定义了。

/*
{

AuThOr Gwj
*/
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin>>a
#define R2(a,b) cin>>a>>b
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=1e6;
int phi[MAXN+2];
LL rest[MAXN+2];
void phi_table(int n) {
  for (int i = 2; i <= n; i++) phi[i] = 0;
  phi[1] = 1;
  for (int i = 2; i <= n; i++)
    if (!phi[i])
      for (int j = i; j <= n; j += i) {
        if (!phi[j]) phi[j] = j;
        phi[j] = phi[j] / i * (i - 1);
      }
}

int main(){
	fastio;
	phi_table(MAXN);
	rb(i,1,MAXN){
		for(int j=i+i;j<=MAXN;j+=i){
			rest[j]+=phi[j/i]*i;
		}
	} 
	rb(i,1,MAXN)
		rest[i]+=rest[i-1];
	while(1){
		int ai;
		R(ai);
		if(!ai) break;
		cout<<rest[ai]<<endl; 
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值