基础数论 1001 LightOJ 1370

来源:互联网 发布:组策略映射网络驱动器 编辑:程序博客网 时间:2024/06/17 19:17

题意:
给一个n个数,假设有数x
->求每个xphi(n)>=x最小的n的和
思路:
预处理一下phi(i)
然后先求出最小的Tab(i)代表phi(n)==i的最小的n
因为有些phi取不到,所以需要取后边的,随便写写就好了

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 100005;const int inf=(1<<28)-1;#define maxp 2000100bool notprime[maxp];int phi[maxp];void get_phi(){    notprime[1]=true;    for(int i=1;i<maxp;++i)    phi[i]=1;    for(int i=2;i<maxp;++i)    if(!notprime[i])    {        phi[i]*=i-1;        for(int j=i+i;j<maxp;j+=i)        {            notprime[j]=true;            int n=j/i;            phi[j]*=i-1;            while(n%i==0)            {                n/=i;                phi[j]*=i;            }        }    }}int Tab[maxp];int main(){    get_phi();    memset(Tab,-1,sizeof(Tab));    for(int i=2;i<maxp;++i)    if(Tab[phi[i]]==-1) Tab[phi[i]]=i;    int flag=-1;    for(int i=maxp-1;i>=1;--i)    if(Tab[i]!=-1)     {        flag=i;        break;    }    for(int i=flag-1;i>=1;--i)    {        if(Tab[i]==-1) Tab[i]=Tab[i+1];        else if(Tab[i]>Tab[i+1]) Tab[i]=Tab[i+1];    }    int T,Case=0;    scanf("%d",&T);    while(T--)    {        int n;        LL Ans=0;        scanf("%d",&n);        for(int i=0;i<n;++i)        {            int x;            scanf("%d",&x);            Ans+=Tab[x];        }        printf("Case %d: %lld Xukha\n",++Case,Ans);    }    return 0;}
0 0
原创粉丝点击