您的位置:首页 > 其它

LightOJ - 1370【欧拉筛法*经典】

2017-07-26 10:52 274 查看
Bamboo Pole-vault is a massively popular sport in Xzhiland. And Master Phi-shoe is a very popular coach for his success. He needs some bamboos for his students, so he asked his assistant Bi-Shoe to go to the market and buy them. Plenty of Bamboos of all
possible integer lengths (yes!) are available in the market. According to Xzhila tradition,

Score of a bamboo = Φ (bamboo's length)

(Xzhilans are really fond of number theory). For your information, Φ (n) = numbers less than n which are relatively prime (having no common divisor other than 1) to n. So, score of a bamboo of length 9 is
6 as 1, 2, 4, 5, 7, 8 are relatively prime to 9.

The assistant Bi-shoe has to buy one bamboo for each student. As a twist, each pole-vault student of Phi-shoe has a lucky number. Bi-shoe wants to buy bamboos such that each of them gets a bamboo with a score greater than or equal to his/her lucky number.
Bi-shoe wants to minimize the total amount of money spent for buying the bamboos. One unit of bamboo costs 1 Xukha. Help him.

Input
Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 10000) denoting the number of students of Phi-shoe. The next line contains n space separated integers denoting the lucky numbers for the students. Each lucky
number will lie in the range [1, 106].

Output
For each case, print the case number and the minimum possible money spent for buying the bamboos. See the samples for details.

Sample Input
3

5

1 2 3 4 5

6

10 11 12 13 14 15

2

1 1

Sample Output
Case 1: 22 Xukha

Case 2: 88 Xukha

Case 3: 4 Xukha

题意:给你一组数字,让你求欧拉函数的值大于等于它的数的和的最小值;

思路:第一种方法不难,重点是第二种方法的学习;

第一种:素数的euler应该是相同euler值最小值,只需要筛查素数就可已,euler(n)=n-1;

第二种,素数筛法预处理,用a数组替换后面euler值比较小的,用b数组表示euler值与最小下标的一个映射;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int max_n=2000010;
int a[max_n+5],b[max_n+5];

void Init()//euler筛法
{
a[1]=0;
for(int i=2;i<=max_n;i++)
a[i]=i;
for(int i=2;i<max_n;i++)
{
if(a[i]==i)
{
for(int j=i;j<max_n;j+=i)
a[j]=a[j]/i*(i-1);
}
}
}

int main()
{
int T,n,k;
long long ans;
Init();
memset(b,0,sizeof(b));
for(int i=1;i<=max_n;i++) a[i]=max(a[i],a[i-1]);//不可省略
for(int i=max_n;i>=1;i--) b[a[i]]=i;
for(int i=1;i<=max_n;i++)
{
if(b[i]==0)
{
int t=i;
while(b[i]==b[t] && t<=max_n)
{
t++;
}
b[i]=b[t];
}
}
b[0]=0;
scanf("%d",&T);
while(T--)
{
static int cnt=0;
ans=0;
scanf("%d",&n);
while(n--)
{
scanf("%d",&k);
ans+=b[k];
}
printf("Case %d: %lld Xukha\n",++cnt,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: