【bzoj 2749】: [HAOI2012]外星人
来源:互联网 发布:算法平台 编辑:程序博客网 时间:2024/05/02 02:01
http://www.lydsy.com/JudgeOnline/problem.php?id=2749
妈蛋官方数据是错的,害我查半天。。。。
留下个草稿或者说在线思路。。。。
my thoughts:
f(x)=0 (x=1)
f(x)=f(phi(x))+1 (else)
那么显然是可以O(n)求出来的
令k=i*prim[j]
f(1)=0
f(i)=f(i-1)+1 (i is a prime)
f(k)=f(phi(k))+1=f(phi(i)*prim[j])+1 (i%prim[j]==0)
f(k)=f(phi(k))+1=f(phi(i)*prim[j]-phi(i))+1 (else)
。。。。到此没啥思路
看看下面的提示
phi(p^q)=(p-1)*p^(q-1)
设x>2
则phi(x)必为偶数
每次变换一次必然消掉一些素因子,产生2
所以最后肯定是累积了大量的2
设g(x)为分解的过程中产生2的个数。。。
g(1)=0
g(2)=1
假设x为奇数
f(x)=g(x)+1
假设x为偶数
f(x)=g(x)
问题转化为如何求g(x)
g(1)=0
g(2)=1
g(2^q)=q
for p>2:
g(p)=g(p-1) (i is a prime)
g(p^q)=q*g(p-1)
g(p1p2)=g(p1)+g(p2) (phi是积性函数)
所以只需要考虑x<=10^5
发现最开始的时候我们已经解决了f(x),那么可以直接求g(x)
#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <cmath>#include <algorithm>using namespace std;#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)#define MS(arr,x) memset(arr,x,sizeof(arr))#define INE(i,u) for(int i=head[u];~i;i=e[i].next)#define LL long longinline const int read(){int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}////////////////////////////////////////////////const int N=100010;int prim[N],f[N],phi[N],cnt;bool flag[N];int g[N];////////////////////////////////////////////////void init(){f[1]=0;rep(i,2,100000){if(!flag[i]) prim[++cnt]=i,phi[i]=i-1,f[i]=f[i-1]+1;for(int j=1;i*prim[j]<=100000&&j<=cnt;j++){int k=i*prim[j];flag[k]=1;if(i%prim[j]==0){phi[k]=phi[i]*prim[j];break;}phi[k]=phi[i]*(prim[j]-1);}}rep(i,2,100000) f[i]=f[phi[i]]+1;g[1]=0;g[2]=1;rep(i,3,100000){if(i&1) g[i]=f[i]-1;else g[i]=f[i];}}////////////////////////////////////////////////void input(){ }void solve(){init(); rep(i,1,read()) { int n=read(); LL ans=0; bool flag=0; //是否为偶数 rep(i,1,n) { int p=read(),q=read(); if(p==1) continue; if(p==2) { flag=1; ans+=q; } else { ans+=(LL)q*g[p-1]; } } if(!flag) ans++; printf("%lld\n",ans); }}////////////////////////////////////////////////int main(){ freopen("_.in","r",stdin); freopen("_.out","w",stdout); input(),solve(); return 0;}
0 0
- 【bzoj 2749】: [HAOI2012]外星人
- BZOJ 2749: [HAOI2012]外星人
- 2749: [HAOI2012]外星人
- 2749: [HAOI2012]外星人
- 【bzoj2749】【HAOI2012】【外星人】【数论】
- bzoj2749: [HAOI2012]外星人
- BZOJ2749: [HAOI2012]外星人
- 【bzoj 2750】: [HAOI2012]Road
- bzoj 2750: [HAOI2012]Road
- BZOJ 2750: [HAOI2012]Road
- [BZOJ 2748][HAOI2012]音量调节
- 【BZOJ 2752】 [HAOI2012]高速公路(road)
- bzoj 2748 [HAOI2012]音量调节
- BZOJ 2752: [HAOI2012]高速公路(road)
- BZOJ P2751:[HAOI2012]容易题
- bzoj 2748 [HAOI2012]音量调节
- Bzoj 2752: [HAOI2012]高速公路(road)
- bzoj 2748: [HAOI2012]音量调节
- [从零开始学设计模式-java]工厂方法模式(Factory Method)
- 归并排序
- 背景图延迟加载(lazyload)技术
- linux下配置ip地址四种方法(图文)
- lowdb 学习
- 【bzoj 2749】: [HAOI2012]外星人
- 删除oracle用户、表空间、及物理文件操作过程
- jsoup初探
- 【CSS】|
- 双系统修复Ubuntu 12.04 GRUB引导
- PostgreSQL 多行变一行
- C++多态的实现原理
- Android 4.4.2 动态添加JNI库方法记录 (二 app应用层)
- 百分制成绩