码迷,mamicode.com
首页 > 其他好文 > 详细

[HAOI2012]外星人 题解

时间:2020-07-16 22:07:16      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:c++   arp   names   var   for   line   提示   lin   print   

人类智慧题。
首先,只有 \(\varphi(1)=\varphi(2)=1\)。再考虑题目中给的提示:

\[\varphi\left(\prod_{i = 1}^m p_i^{q_i}\right) = \prod_{i = 1}^m (p_i - 1)p_i^{q_i-1} \]

那么题目答案显然可以转化为一个数在操作过程中出现了多少个 \(1\)
\(f(x)\) 表示 \(x\) 在操作过程中产生了多少个 \(1\),现在来发掘一下性质。
因为贡献互不影响,所以有 \(f(p)=f(p-1)\) 以及 \(\forall a,b,f(ab)=f(a)+f(b)\)
然后就可以直接筛了,注意特判没有质因子 \(2\) 的情况。

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+5;
int n=1e5,m,f[N],pri[N];
long long ans=1; bool v[N];

int main()
{
    f[1]=1;
    for(int i=2;i<=n;++i)
    {
        if(!v[i]) pri[++pri[0]]=i,f[i]=f[i-1];
        for(int j=1;j<=pri[0]&&i*pri[j]<=n;++j)
        {
            v[i*pri[j]]=1; f[i*pri[j]]=f[i]+f[pri[j]];
            if(i%pri[j]==0) break;
        }
    }
    int Case; scanf("%d",&Case);
    while(Case--)
    {
        scanf("%d",&m); ans=0; bool fl=1;
        for(int i=1,x,c;i<=m;++i)
        {
            scanf("%d%d",&x,&c),ans+=1LL*f[x]*c;
            if(x==2) fl=0;
        }
        printf("%lld\n",ans+fl);
    }
    return 0;
}

[HAOI2012]外星人 题解

标签:c++   arp   names   var   for   line   提示   lin   print   

原文地址:https://www.cnblogs.com/wzzyr24/p/13324362.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!