light oj 1370(欧拉筛)

一开始以为求欧拉函数
//78ms

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 1000;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int prime[maxn], isprime[maxn], phi[maxn], ans[maxn];

void get_phi(){//欧拉函数 
	int cnt = 0;
	int d = 0;
	for(int i = 2; i < maxn; ++ i){
		if(isprime[i] == 0)
			prime[cnt ++] = i, phi[i] = i-1;
		for(int j = d; j <= phi[i]; ++ j)
			ans[j] = i;
		d = max(d, phi[i]+1);
		for(int j = 0; j < cnt && prime[j] * i < maxn; ++ j){
			isprime[prime[j] * i] = 1;
			if(i % prime[j] == 0){
				phi[i * prime[j]] = phi[i] * prime[j];
				break;
			}
			phi[i * prime[j]] = phi[i] * phi[prime[j]];
		}
	}
}
int main(){
	int t, cnt = 1;
	get_phi();
	scanf("%d", &t);
	while(t--){
		int k, a;
		scanf("%d", &k);
		ll sum = 0;
		while(k--){
			scanf("%d", &a);
			sum += ans[a];
		}
		printf("Case %d: %lld Xukha\n", cnt++, sum);
	}
}

后来发现和欧拉函数无关
//58ms

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 1000;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int prime[maxn, ans[maxn];
bool isprime[maxn];

void get_ans(){//欧拉筛 
	int cnt = 0;
	int d = 1;
	for(int i = 2; i < maxn; ++ i){
		if(!isprime[i]){
			prime[cnt ++] = i;
			for(int j = d; j <= i-1; ++ j)
				ans[j] = i;
			d = i;
		}	
		for(int j = 0; j < cnt && prime[j] * i < maxn; ++ j){
			isprime[prime[j] * i] = true;
			if(i % prime[j] == 0)
				break;
		}
	}
}
int main(){
	int t, cnt = 1;
	get_ans();
	scanf("%d", &t);
	while(t--){
		int k, a;
		scanf("%d", &k);
		ll sum = 0;
		while(k--){
			scanf("%d", &a);
			sum += ans[a];
		}
		printf("Case %d: %lld Xukha\n", cnt++, sum);
	}
}

最后发现只和质数有关
//48ms bool 数组比 int 数组处理快

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 1000;
typedef long long ll;
int isprime[maxn];

void is_prime(){//埃氏筛  
    for(int i = 2; i*i < maxn; ++ i){
        if(!isprime[i]){
            for(int j = i*i; j <= maxn; j += i){
                isprime[j] = 1;
            }
        }
    }
}

int main(){
	int t, cnt = 1;
	is_prime();
	scanf("%d", &t);
	while(t--){
		int k, a;
		scanf("%d", &k);
		ll sum = 0;
		while(k--){
			scanf("%d", &a);
			for(int temp = a+1; ; temp++){
                if(isprime[temp] == 0){
                    sum += temp;
                    break;
                }
            }
		}
		printf("Case %d: %lld Xukha\n", cnt++, sum);
	}
}
posted @ 2020-08-04 23:23  wansheking  阅读(76)  评论(0)    收藏  举报