Bi-shoe and Phi-shoe(欧拉函数)
题意:
给一些数Ai(第 i 个数),Ai这些数代表的是某个数欧拉函数的值,我们要求出数 Ni 的欧拉函数值不小于Ai。而我们要求的就是这些 Ni 这些数字的和sum,而且我们想要sum最小,求出sum最小多少。
解题思路:
要求和最小,我们可以让每个数都尽量小,那么我们最后得到的肯定就是一个最小值。
给定一个数的欧拉函数值ψ(N),我们怎么样才能求得最小的N?
我们知道,一个素数P的欧拉函数值ψ(P)=P-1。所以如果我们知道ψ(N),那么最小的N就是最接近ψ(N),并且大于ψ(N)的素数。我们把所有素数打表之后再判断就可以了。
也就是说,一个数的欧拉函数值ψ(N),要使N值最小(要求:数 N 的欧拉函数值大于等于ψ(N)),则N一定是大于ψ(N)的第一个质数。
个人理解,比如N=7,ψ(N)=6,还能求出ψ(N)=6,但是比7小的N吗?显然不能,所以根据逆否命题什么的,就可以证上面了(这属于个人理解,也可能有错,所以不用太相信)
在prime中找的时候用了二分,能更快些,不用也应该能过吧。
#include <bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; typedef long long ll; #define PI(A) printf("%d\n",A) #define SI(N) scanf("%d",&(N)) #define SII(N,M) scanf("%d%d",&(N),&(M)) #define cle(a,val) memset(a,(val),sizeof(a)) #define rep(i,b) for(int i=0;i<(b);i++) #define Rep(i,a,b) for(int i=(a);i<=(b);i++) #define reRep(i,a,b) for(int i=(a);i>=(b);i--) const double EPS= 1e-9 ; /* ///////////////////////// C o d i n g S p a c e ///////////////////////// */ const int MAXN= 1000000 + 5 ; int a[10000+5]; //素数筛模板 int prime[MAXN]; //第i个素数 bool is_prime[MAXN+1];//is_prime[i]为true代表i是素数 //返回n以内素数的个数 int sieve(int n) { int p=0; for (int i=0; i<=n; i++) is_prime[i]=true; is_prime[0]=is_prime[1]=false; for (int i=2; i<=n; i++) { if (is_prime[i]) { prime[p++]=i; for (int j=2*i; j<=n; j+=i) is_prime[j]=false; } } return p; } int T; int main() { int K=sieve(MAXN); int o; SI(o); while(o--) { int n; SI(n); ll ans=0; rep(i,n) { int d; SI(d); ans+=*lower_bound(prime,prime+K,d+1); } printf("Case %d: %lld Xukha\n",++T,ans); } return 0; }