2749: [HAOI2012]外星人

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 377  Solved: 199
[Submit][Status]

Description

 

Input

 

Output

输出test行,每行一个整数,表示答案。

Sample Input

1
2
2 2
3 1

Sample Output

3

HINT

Test<=50 Pi<=10^5,1<=Q1<=10^9

Source

题解:

终于把这题搞掉了。。。

研究了一下此题的两种解法。

一种是直接求 这个数一直phi,最后能phi出多少个2,就是答案。

一种是利用递推的思想,用 f[i]表示i phi几次能变成1,有递推式 f[i]=f[phi(i)]+1

这两种方法都可以求出正确结果,让我们讨论一下为什么这样就可以:

首先,

题中给出了这样的公式,然后我们发现每次phi只能使每个质数的指数-1,然后这个 p[i]-1会继续质因数分解然后加在其它比它小的质数的指数上。

然后我们就会发现,2被phi的次数一定是最多的!!!

假设还有另一个质数 x 那么 phi(x)会多出1个2,所以 phi(2)的次数>=phi(x) 的次数!

所以 2被phi了多少次,ans就是多少!2还没有被phi完,其他质数的质数就已经都为0了!

然后呢?我们得到了一个什么结论?一个数被phi成1的次数就等于它phi了多少次2

这样的话 f[x]就等于 x phi 2的次数。

然后两种方法就统一了。

这也就解释了为什么不同的质数之间的被phi的次数是可以叠加的,因为我们加的实际上是同一个质数2的次数,而phi每次只能让2的指数-1!!!

还有一些细节要注意,这里就不提出了。

代码:直接递推求 f[x](求phi写萎了。。。)(这里面的偶数求的会比实际少1,因为并没有计入第一次phi的2)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int m=;
int p[m],f[m],n,t,i,j,x,y;
long long ans;
int main()
{
for(i=;i<=m;i++) p[i]=i;
for(i=;i<=m;i++)
if(p[i]==i)
for(j=i;j<=m;j+=i) p[j]=p[j]/i*(i-);
p[]=,f[]=-;
for(i=;i<=m;i++) f[i]=f[p[i]]+;
f[]++,f[]++;
cin>>t;
while(t--)
{
scanf("%d",&n);
for(ans=,i=;i<=n;i++)
{
scanf("%d%d",&x,&y);
if(x==) ans--;
ans+=(long long)f[x]*y;
}
printf("%lld\n",ans);
}
return ;
}

代码:求2的个数

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 100000+5
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=;char ch=getchar();
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x;
}
int tot,p[maxn],f[maxn];
bool v[maxn];
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
f[]=;
for2(i,,maxn)
{
if(!v[i]){p[++tot]=i;f[i]=f[i-];}
for1(j,tot)
{
int t=i*p[j];
if(t>maxn)break;
v[t]=;
f[t]=f[i]+f[p[j]];
if(i%p[j]==)break;
}
}
int m=read();
while(m--)
{
int n=read();ll ans=;
for1(i,n)
{
int x=read(),y=read();
if(x==)ans--;
ans+=(ll)f[x]*y;
}
printf("%lld\n",ans);
}
return ;
}

其实f[x]=求2的个数,这里只是用了不同的方法。

BZOJ2749: [HAOI2012]外星人的更多相关文章

  1. BZOJ2749 HAOI2012外星人(数论)

    不妨把求φ抽象成把将每个位置上的一个小球左移一格并分裂的过程,那么即求所有球都被移到1号格子的步数. 显然要达到1必须先到达2.可以发现每次分裂一定会分裂出2号位的球,因为2以外的质数一定是奇数.以及 ...

  2. 【bzoj2749】[HAOI2012]外星人

    2749: [HAOI2012]外星人 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 677  Solved: 360[Submit][Status][ ...

  3. Bzoj 2749: [HAOI2012]外星人 欧拉函数,数论,线性筛

    2749: [HAOI2012]外星人 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 568  Solved: 302[Submit][Status][ ...

  4. 【BZOJ 2749】 2749: [HAOI2012]外星人 (数论-线性筛?类积性函数)

    2749: [HAOI2012]外星人 Description Input Output 输出test行,每行一个整数,表示答案. Sample Input 1 2 2 2 3 1 Sample Ou ...

  5. [HAOI2012]外星人

    题目大意: 告诉你一个数n,求满足φ^x(n)=1的x. 思路: 首先我们可以发现满足φ(n)=1的数只有2,也就是说你得到最终的结果,最后一步肯定是φ(2). 同时,可以发现φ(φ(2^k))=φ( ...

  6. JZYZOJ1524 [haoi2012]外星人 欧拉函数

    http://172.20.6.3/Problem_Show.asp?id=1524 大概可以算一个结论吧,欧拉函数在迭代的时候,每次迭代之后消去一个2,每个非2的质因子迭代一次又(相当于)生成一个2 ...

  7. 题解 P2350 【[HAOI2012]外星人】

    题目链接 还是本宝宝写题解的一贯习惯 $ :$ 先吐槽吐槽这道题$……$ 相信不少同学第一眼一定没有看懂题.(因为我也没看懂) ~~初中~~数学知识: 对于函数 $ f(x)$ 有 $f^{-1}(x ...

  8. 2749: [HAOI2012]外星人

    首先像我一样把柿子画出来或者看下hint 你就会发现其实是多了个p-1这样的东东 然后除非是2他们都是偶数,而2就直接到0了 算一下2出现的次数就好 #include<cstdio> #i ...

  9. BZOJ 2749 [HAOI2012]外星人

    题解:对每一个>2的质数分解,最后统计2的个数 注意:如果一开始没有2则ans需+1,因为第一次求phi的时候并没有消耗2 WA了好几遍 #include<iostream> #in ...

随机推荐

  1. Java POI导入Excel文件

    今天在公司需要做个导入Excel文件的功能,所以研究了一下,参考网上的一些资料总算是做出来了,在此记录一下防止以后忘记怎么弄. 本人用的是poi3.8,所以需要的JAR包如下: poi-3.8.jar ...

  2. 【小TIP】记录各种错误【更新中】

    最好程序一遍通过,为了提高代码能力,这里将用TIP的形式记录来犯过的错误.不断更新中. *已经转移到闪存.. [150214]WA:检查是否数组开小了. [150212]WA:如果程序中有乘号,需要留 ...

  3. POJ 1584 A Round Peg in a Ground Hole 判断凸多边形,判断点在凸多边形内

    A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5456   Acc ...

  4. 刚入门的easyui

    这两天看了下easyui的教学先说说自己的一些小小理解吧! ----在使用easyui中也遇到了一个问题 : Uncaught TypeError:cannot call method ‘offset ...

  5. oracle 关于动态执行语句 execute immediate 的用法

    当在开发的应用场景中 数据库处理复杂业务逻辑里用到 SQL 语句拼接    可以用  execute immediate   来执行语 举个例子 insert into tb_temp_public( ...

  6. 后台地址报错:Service Unavailable

    首先考虑数据库是否打开? 第二重启IIS试试: 重启下iis试试(cmd接着iisreset) 再次访问就正常了,可以借鉴,但不一定就只是这一种原因.

  7. Linux filesystem structures.

    1. / – Root Every single file and directory starts from the root directory. Only root user has write ...

  8. JavaScript--声明提前

    声明提前(hoist): 在正式执行程序前,都会将所有var声明的变量和function声明的函数提前到*当前作用域*的顶部集中创建. 但是,赋值留在原地. console.log(a);//unde ...

  9. MYSQL一对多,两表查询合并数据

    select a.askid,a.title,GROUP_CONCAT(b.message SEPARATOR '----') as content from gg_ask as a join gg_ ...

  10. jQuery常用事件

    1.$(document).ready() $(document).ready()是jQuery中响应JavaScript内置的onload事件并执行任务的一种典型方式.它和onload具有类似的效果 ...