HAOI2012 外星人

Posted fengxunling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HAOI2012 外星人相关的知识,希望对你有一定的参考价值。

题目链接 戳我

能看懂的题目翻译:给你N,让你求(N=phi N)多少次N=1.

根据唯一分解定理,以及题目中对(phi)的计算提示,我们知道,每一次计算,可以使得其中至多一个2变成1,不断地重复这个操作,这个数就会越来越小,直到达到1.

所以我们求出来一个数中有多少个2作为因子即可。

nlogn是可以暴力做的,但是对于1e6的数据范围可能略大了一些,所以我们考虑线性做法。

(f(n))表示n中有多少个2.

对于一个素数,(f(n)=f(n-1))。对于一个数a*b,(f(ab)=f(a)+f(b))

之后就可以仿照欧拉筛来写了。

最后注意一个细节,如果整个数里面没有2这个因子的话,(那这显然是奇数了吧)我们还需要额外的一步,使得它拥有2作为因子,所以ans++。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define MAXN 100010
using namespace std;
int t,m,x,y,tot;
bool flag=false;
long long ans;
long long f[MAXN],not_prime[MAXN],prime[MAXN];
inline void init()
{
    f[1]=1;
    for(int i=2;i<=MAXN-10;i++)
    {
        if(not_prime[i]==0) prime[++tot]=i,f[i]=f[i-1];
        for(int j=1;j<=tot&&i*prime[j]<=MAXN-10;j++)
        {
            not_prime[i*prime[j]]=1;
            f[i*prime[j]]=f[i]+f[prime[j]];
            if(i%prime[j]==0) break;
        }
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    freopen("ce.out","w",stdout);
    #endif
    scanf("%d",&t);
    init();
    while(t--)
    {
        ans=0;
        flag=false;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if(x==2) flag=true;
            ans+=1ll*f[x]*y;

        }
        if(flag==false) ans++;
        printf("%lld
",ans);
    }
    return 0;
}

以上是关于HAOI2012 外星人的主要内容,如果未能解决你的问题,请参考以下文章

[HAOI2012]外星人 题解

BZOJ 2749 [HAOI2012]外星人

[HAOI2012] 外星人 - 数论,欧拉函数

HAOI2012 外星人

JZYZOJ1524 [haoi2012]外星人 欧拉函数

bzoj2748: [HAOI2012]音量调节(背包)