HDU 5528 Count a*b ACM/ICPC 2015 Changchun(数论)
来源:互联网 发布:淘宝u站刷粉丝软件 编辑:程序博客网 时间:2024/05/21 11:57
Count a * b
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 811 Accepted Submission(s): 299
Problem Description
Marry likes to count the number of ways to choose two non-negative integers
Let's denote
She has calculated a lot of
Give you
Input
The first line contains an integer
Output
For each test case, print one integer
Sample Input
26514
Sample Output
26328194
Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
非常棒的一道数论题,而且还是一道金牌题,A了几乎就是金牌……
至于具体推到姿势,由于符号难写,我就用某个大神的手迹来说明吧,大神写的真的很好。原文地址:http://blog.csdn.net/firstlucker/article/details/49336427
下面,我解释一下画横线那一步。之前已经是求到了sigma(gcd(a,x)),相当于1~x中所有数字与x的gcd之和。BTW,关于这个可以再说一篇文章,POJ 2480就是只求这个东西,这个利用积性可以巧妙的解决,具体可以看下一篇文章。在这里我们可以考虑x的每个约数作为gcd的次数,然后计算求和。于是我们就可以按照画横线那一步那样,枚举x的约数d,然后对于每一个d统计有多少个合法的。而所谓合法就是两个数字除以这个约数之后的gcd为1。a是从1~x取的,如果a不是d的倍数显然可以忽略,于是我们可以继续往下化简,得到横下往下那一步,用i代替a/d。此时i的取值是1~x/d,那么这个判定条件就变成了1~x/d中有多少个数字与x/d的gcd为1,或者说互质。那么很顺其自然的就可用欧拉函数写出最后的式子。
但是即使推到了这一步我们还是不能在规定时间内解出答案,因为很多组数据,而且n可以取1e9,也不可能预处理出那么多的phi。于是我们还得继续化简。
接着解释这个。首先是第一个画横线那里,说实话,我第一次看到的时候真的是一脸懵逼。然后后来慢慢回想起来,这是一个关于整数合式的一个定理,在《具体数学》书中也出现过。具体来说是这样子的:
知道了这个转换之后,我们就可以继续说事了。然后看第二条横线那,这个又是如何转换过来的呢?上面一行想到与是n/d所有约数的欧拉函数之和,下面画横线那变成了n/d。其实这是一个定理,一个数字x的所有约数的欧拉函数之后等于它本身。这样我们就可以顺其自然的化简到最后一行了,其中最后一行中h(n)表示n的约数个数。知道此时,我们算是比较完美的解决了后面那一部分的东西,但是前半部分东西还是不太好,约数的平方和,如果一个约数一个的算还是会TLE,前面努力就白费了,于是还要继续找性质化简。
接下来,我们想到了积性。可以证明一个数字的约数平方和是一个积性函数,不仅如此,一个数约数的k次方和都是积性函数。所以我们可以得出最终式子:
然后具体细节的话还要注意,本题常数卡的比较厉害,需要预处理出素数表。然后在运算过程中虽然说对2^64取模(用unsigned long long即可),但是还是要做一些防止溢出的处理,因为有些东西本来不会溢出的,但是中间溢出的话会导致WA。具体见代码,还是非常刺激的一道题:
#include<bits/stdc++.h>#define ULL unsigned long long#define N 101000using namespace std;int prime[N],tot,n,m,t;bool isprime[N];void getlist(int listsize)//欧拉筛预处理出素数表{ memset(isprime,1,sizeof(isprime)); isprime[1]=false; tot=0; for(int i=2;i<listsize;i++) { if(isprime[i]) prime[++tot]=i; for(int j=1;j<=tot&&i*prime[j]<listsize;j++) { isprime[i*prime[j]]=false; if(i%prime[j]==0)break; } }}int main(){ getlist(N); int T_T; cin>>T_T; while(T_T--) { scanf("%d",&n); ULL x=1,y=n,p; for(int i=1;prime[i]*prime[i]<=n;i++) { if (n%prime[i]==0) { t=1; p=1; while(n%prime[i]==0) t++,n/=prime[i],p*=prime[i]; p*=prime[i]; y*=t; ULL a=(p-1)/(prime[i]-1),b=p+1,c=prime[i]+1; x*=((a/c)*(b/c)*c+a%c*(b/c)+b%c*(a/c));//防止溢出操作 } } if (n>1) x*=((ULL)n*n+1),y*=2; printf("%I64u\n",x-y); } return 0;}
- HDU 5528 Count a*b ACM/ICPC 2015 Changchun(数论)
- [数论] ACM 2015 Changchun B Count a*b
- HDU 5536 Chip Factory ACM/ICPC 2015 Changchun(Trie)
- HDU 5528Count a * b(数论)
- Regional 2015 - Asia Changchun - B Count a × b
- 2015 ACM/ICPC Asia Regional Changchun Online hdu 5438
- hdu 5438 Ponds 2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5441 Travel(2015 ACM/ICPC Asia Regional Changchun Online)
- HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)
- HDU 5437 Alisha’s Party (Priority_queue)2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5438 Ponds (拓扑排序+DFS)2015 ACM/ICPC Asia Regional Changchun Online
- HDU 5446 Unknown Treasure ACM/ICPC 2015 Changchun Online(Lucass+CRT)
- HDU 5445 Food Problem ACM/ICPC 2015 Changchun Online(二进制优化多重背包)
- HDU 5449 Robot Dog ACM/ICPC 2015 Changchun Online(数学期望+LCA)
- HDU 5534 Partial Tree ACM/ICPC 2015 Changchun(完全背包)
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5901 Count Primes (模板 + 数论知识)★
- hdu 5528 Count a * b 2015长春区域赛 数论 分析
- HDOJ-5446/2015 ACM/ICPC Asia Regional Changchun Online 1010(数论)
- network
- win10使用tensorboard 0.0.0.0:6006无法访问
- 织梦dedecms删除文章的同时删除该文章下的图片和附件
- 机器学习常用算法三:协同过滤
- struts常用配置
- HDU 5528 Count a*b ACM/ICPC 2015 Changchun(数论)
- Spring处理循环依赖
- 女程序媛的悲哀?凭什么
- 1、LambdaToSql 发布1.0.0.1版本
- HTML基础学习一
- DrawerLayout
- Ubuntu 16.04远程登录服务器--ssh的安装和配置
- PL/SQL使用SQLServer字体
- java深入学习二之关键字