BZOJ2749: [HAOI2012]外星人
2749: [HAOI2012]外星人
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 377 Solved: 199
[Submit][Status]
Description
Input
Output
输出test行,每行一个整数,表示答案。
Sample Input
2
2 2
3 1
Sample Output
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]外星人的更多相关文章
- BZOJ2749 HAOI2012外星人(数论)
不妨把求φ抽象成把将每个位置上的一个小球左移一格并分裂的过程,那么即求所有球都被移到1号格子的步数. 显然要达到1必须先到达2.可以发现每次分裂一定会分裂出2号位的球,因为2以外的质数一定是奇数.以及 ...
- 【bzoj2749】[HAOI2012]外星人
2749: [HAOI2012]外星人 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 677 Solved: 360[Submit][Status][ ...
- Bzoj 2749: [HAOI2012]外星人 欧拉函数,数论,线性筛
2749: [HAOI2012]外星人 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 568 Solved: 302[Submit][Status][ ...
- 【BZOJ 2749】 2749: [HAOI2012]外星人 (数论-线性筛?类积性函数)
2749: [HAOI2012]外星人 Description Input Output 输出test行,每行一个整数,表示答案. Sample Input 1 2 2 2 3 1 Sample Ou ...
- [HAOI2012]外星人
题目大意: 告诉你一个数n,求满足φ^x(n)=1的x. 思路: 首先我们可以发现满足φ(n)=1的数只有2,也就是说你得到最终的结果,最后一步肯定是φ(2). 同时,可以发现φ(φ(2^k))=φ( ...
- JZYZOJ1524 [haoi2012]外星人 欧拉函数
http://172.20.6.3/Problem_Show.asp?id=1524 大概可以算一个结论吧,欧拉函数在迭代的时候,每次迭代之后消去一个2,每个非2的质因子迭代一次又(相当于)生成一个2 ...
- 题解 P2350 【[HAOI2012]外星人】
题目链接 还是本宝宝写题解的一贯习惯 $ :$ 先吐槽吐槽这道题$……$ 相信不少同学第一眼一定没有看懂题.(因为我也没看懂) ~~初中~~数学知识: 对于函数 $ f(x)$ 有 $f^{-1}(x ...
- 2749: [HAOI2012]外星人
首先像我一样把柿子画出来或者看下hint 你就会发现其实是多了个p-1这样的东东 然后除非是2他们都是偶数,而2就直接到0了 算一下2出现的次数就好 #include<cstdio> #i ...
- BZOJ 2749 [HAOI2012]外星人
题解:对每一个>2的质数分解,最后统计2的个数 注意:如果一开始没有2则ans需+1,因为第一次求phi的时候并没有消耗2 WA了好几遍 #include<iostream> #in ...
随机推荐
- Java POI导入Excel文件
今天在公司需要做个导入Excel文件的功能,所以研究了一下,参考网上的一些资料总算是做出来了,在此记录一下防止以后忘记怎么弄. 本人用的是poi3.8,所以需要的JAR包如下: poi-3.8.jar ...
- 【小TIP】记录各种错误【更新中】
最好程序一遍通过,为了提高代码能力,这里将用TIP的形式记录来犯过的错误.不断更新中. *已经转移到闪存.. [150214]WA:检查是否数组开小了. [150212]WA:如果程序中有乘号,需要留 ...
- 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 ...
- 刚入门的easyui
这两天看了下easyui的教学先说说自己的一些小小理解吧! ----在使用easyui中也遇到了一个问题 : Uncaught TypeError:cannot call method ‘offset ...
- oracle 关于动态执行语句 execute immediate 的用法
当在开发的应用场景中 数据库处理复杂业务逻辑里用到 SQL 语句拼接 可以用 execute immediate 来执行语 举个例子 insert into tb_temp_public( ...
- 后台地址报错:Service Unavailable
首先考虑数据库是否打开? 第二重启IIS试试: 重启下iis试试(cmd接着iisreset) 再次访问就正常了,可以借鉴,但不一定就只是这一种原因.
- Linux filesystem structures.
1. / – Root Every single file and directory starts from the root directory. Only root user has write ...
- JavaScript--声明提前
声明提前(hoist): 在正式执行程序前,都会将所有var声明的变量和function声明的函数提前到*当前作用域*的顶部集中创建. 但是,赋值留在原地. console.log(a);//unde ...
- MYSQL一对多,两表查询合并数据
select a.askid,a.title,GROUP_CONCAT(b.message SEPARATOR '----') as content from gg_ask as a join gg_ ...
- jQuery常用事件
1.$(document).ready() $(document).ready()是jQuery中响应JavaScript内置的onload事件并执行任务的一种典型方式.它和onload具有类似的效果 ...