LightOJ 1370(欧拉函数)

题意: T T 组数据,给定长度为 n n 的序列 a a ,对于每个 a i a_i 求出 φ ( b i ) a i \varphi(b_i)\geq a_i 的最小 b i b_i
题解:
1. 1. 对于每个数 a i a_i ,一定是找到最小的欧拉函数大于等于 a i a_i 的质数。
对于一个数 p r i m e [ i ] x < p r i m e [ i + 1 ] prime[i]\leq x < prime[i+1] ,我们要证明任意 y [ x + 1 , p r i m e [ i + 1 ] ] y\in[x+1,prime[i+1]] φ ( y ) x \varphi(y)\geq x 当且仅当 y = p r i m e [ i + 1 ] y=prime[i+1] 时。(不会证
2. 2. 暴力枚举每个数即可, 1 0 8 + 10 10^8+10 内的最大两个素数间隔为 220 220
注意:本题中 a i = 1 a_i=1 时的 b i = 2 b_i=2

#include<bits/stdc++.h>
using namespace std;

const int N = 10010;
const int maxn = 1000010;
int q[N], n;

int pri[maxn], cnt;
bool st[maxn];
void xs(int n) {
	st[0] = st[1] = true;
	for(int i = 2; i <= n; ++i) {
		if(!st[i]) pri[++cnt] = i;
		for(int j = 1; j <= cnt && 1ll * i * pri[j] <= n; ++j) {
			st[i * pri[j]] = true;
			if(i % pri[j] == 0) break;
		}
	}
} 

int b_s(int x) {
	int l = 1, r = cnt;
	while(l < r) {
		int mid = l + r >> 1;
		if(pri[mid] - 1 >= x) r = mid;
		else l = mid + 1;
	}
	return l;	 
}

long long solve() {
	scanf("%d", &n);
	long long res = 0; 
	for(int i = 1, x; i <= n; ++i) {
		scanf("%d", &x);
		if(x == 1) res += 2;
		else { 
			int t = b_s(x);
			res += pri[t];
		} 
	} 
	return res;
}

int main()
{
	xs(maxn - 1);
	int T = 1; scanf("%d", &T);
	for(int i = 1; i <= T; ++i) {
		printf("Case %d: %lld Xukha\n", i, solve());
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43900869/article/details/107533115