LightOJ1370-Bi-shoe and Phi-shoe 【欧拉函数】
Bi-shoe and Phi-shoe
题目
给出n个数字的序列a[],对于每个数字ai找到一个欧拉函数值大于等于ai的数bi,求找到的所有数bi的最小值之和sum
分析
这是第二次写关于欧拉函数的题,这是使用了欧拉函数打表的模板,然后再处理一下最优值就可以了,其实也可以排序之后用二分。
需要处理的地方:
for(int i = 1;i<maxn;i++) mp[E[i]] = min(mp[E[i]],i)
这一句是将欧拉函数值E[i]一样的,取i较小的那个for(int i = maxn-2;i>=1;i--) if(mp[i+1]) mp[i] = min(mp[i+1],mp[i])
这句是从后往前取最优值,比如mp[8] = 15,mp[9] = inf,mp[10] = 11
也就是欧拉值为8最小是15,欧拉值为9的没有(用的无穷大表示),欧拉值为10最小是11,但是本题需要节省成本,所以需要mp[9] = min(mp[9],mp[10]) = 11,mp[8]=min(mp[8],mp[9]),
所以mp[8] == mp[9] == mp[10] = 11
,一个人的luckly值为8,9,10
的时候选11
长的杆子能节省成本。
AC代码
#include <iostream> #include <algorithm> #include <map> #include <cstring> #include <stdio.h> using namespace std; const int maxn = 1101000; int T,N; int E[maxn],mp[maxn]; void init() //欧拉函数值打表,并求出题目中所有答案 { memset(mp,0x3f3f3f3f,sizeof mp); for(int i=2;i<maxn;i++){ if(!E[i]) for(int j=i;j<maxn;j+=i){ if(!E[j]) E[j]=j; E[j] = E[j]/i*(i-1); } } for(int i = 1;i<maxn;i++) mp[E[i]] = min(mp[E[i]],i); for(int i = maxn-2;i>=1;i--){ if(mp[i+1]) mp[i] = min(mp[i+1],mp[i]); } } int main(){ init(); int kase = 1; cin>>T; while(T--){ scanf("%d",&N); int tmp;long long res = 0; for(int i = 1;i<=N;i++){ scanf("%d",&tmp); res += mp[tmp]; } printf("Case %d: %lld Xukha\n",kase++,res); } return 0; }