您的位置:首页 > 大数据 > 人工智能

zoj 3175 Number of Containers

2011-09-20 19:38 162 查看
/*
* zoj3175.c
*
*  Created on: 2011-9-20
*      Author: bjfuwangzhu
*/
/*
题目描述:给定一个n,求1,2。。。n所有数的约数个数和f(n)
例如f(5)=10-5,f(4)=8-4
由于这个n非常大,故有两种思考方向,第一种是找该函数的递推或者公式,貌似很难而且每有头绪
还有种思考的方式就是我们按段来统计,就是统计区间上有多少个数含有这个约数,我们是可以O(1)时间计算的
接下来就是如何分这个段,其实这个问题反映到坐标系中就是对于x*y<=n,我们要找在这个图形中所有的正整数点
我们用直线x=y把这个图形分成两部分,显然这两部分是对称的,于是我们可以令i=[1,sqrt(n)] 累加n/i (其实就是我之前说的段)
这个再*2,但是注意到对角线上的元素我们计算了两次,故要减去k*k(k=sqrt(n))
为什么是这个我们把整点看成基点,就是说面积通过数基点得到,我们对应到坐标上是双曲线,发现每次重算的部分叠加起来正好是一个正方形
内所有的整点,故是k*k
*/

#include<stdio.h>
#include<math.h>
typedef long long LL;
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int T, i, te, n;
LL res;
while (~scanf("%d", &T)) {
while (T--) {
scanf("%d", &n);
te = (int) sqrt(n * 1.0);
for (i = 1, res = 0; i <= te; i++) {
res += n / i;
}
res = (res << 1) - te * te;
res -= n;
printf("%lld\n", res);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: