http://acm.hdu.edu.cn/showproblem.php?pid=3208
2009-5-30东华大学全国邀请赛 I题 Integer Power 解题分析
Description
LMY and YY are number theory lovers. They like to find and solve some interesting number
theory problems together. One day, they become interested in some special numbers, which
can be expressed as powers of smaller numbers.
For example, 9=3^2, 64=2^6, 1000=10^3 …
For a given positive integer y, if we can find a largest integer k and a smallest positive
integer x, such that x^k=y, then the power of y is regarded as k.
It is very easy to find the power of an integer. For example:
The power of 9 is 2. 9的次数是2
The power of 64 is 6. 64的次数是6
The power of 1000 is 3. 1000的次数是3
The power of 99 is 1. 99的次数是1
The power of 1 does not exist. 1的次数不存在
But YY wants to calculate the sum of the power of the integers from a to b. It seems not easy.
Can you help him?
Input
The input consists of multiple test cases.
For each test case, there is one line containing two integers a and b. (2<=a<=b<=10^18)
End of input is indicated by a line containing two zeros.
Output
For each test case, output the sum of the power of the integers from a to b.
Sample Input
2 10
248832 248832
0 0
Sample Output
13
5
计算 a 到 b 的所有 数的次数的和 sum(a,b) ,a<=b.
9的次数是2 , 64的次数是6 , 1000的次数是3, 99的次数是1, 1的次数不存在
sum(a,b)= sum(2,b)-sum(2,a-1);
例: a=2,b=20
2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20; b-1=19个数
2,3,5,6,7,10,11,12,13,14,15,17,18,19,20, 1 次方数 15个
4,9 , 2 次方数 2个
8, 3 次方数 1个
16, 4 次方数 1个
sum(2,20)= 1*15+ 2*2 +3*1+4*1 =26
f[i][b]:[2,b]中 i次方 数的个数
f[1][b]+f[2][b]+...f[k][b]=b-1;
sum(2,b)= 1*f[1][b]+ 2*f[2][b] +3*f[3]+...k*f[k][b] , 2^k<=b, 2^(k+1)>b
根据下列性质计算
性质: f[i][b] = f[1][b^(1/i)] ,即 [2,b]中 i次方数的个数等于 [2,b0]中的1次方数
的个数. 这里 b0^i<=b,(b0+1)^i>b
例:[2,100]中 2次方数的个数 f[2][100]等于
[2,10]= {2,3,4,5,6,7,8,9,10} 中
1次方数 {2,3,5,6,7,10} 的个数 f[1][10]
sum(2,100) =124
2,3,4,5,6,7,8,9,10,11,12,13,14,....,100 ; 99个数
2,3,4,5,6,7,8,9,10 ; 6 个 2次方 数 6*2=12
2,3,4 ; 2 个 3次方 数 2*3=6
2 3; 2 个 4次方 数 2*4=8
2 ; 1 个 5次方 数 1*5=5
2 ; 1 个 6次方 数 1*6=6
99-6-2-2-1-1= 87 个 1次方 数 87*1=87
12+6+8+5+6+87=124
一些计算实例:
Sample input
41 116301521603347921
6334 493155062500000000
19169 61129682565918976
11478 742858102364602896
26962 358187043473391616
5705 627487403488050625
23281 80172749696989041
9961 58120048561
2995 20338001141940496
4827 873208173609216
0 0
Sample output
116301521945408248
493155063203898480
61129682813978378
742858103228376898
358187044073341627
627487404281977151
80172749981025516
58120289895
20338001285131386
873208203364055
input and output
2 1000000000000000000
1000000001002087980
2 10000000000000000
10000000100462306
2 100000000000000
100000010104622
2 1000000000000
1000001024696
2 10000000000
10000106258
2 100000000
100011742
2 1000000
1001510
2 10000
10238
2 100
124
http://acm.hdu.edu.cn/showproblem.php?pid=3215
题目大意是计算2^0到2^n中每个数的最左边一位,然后记录1-9每个数字出现的次数并依次打印出来;
考虑到n的范围 [0,10000], 不可能去计算 2^n
先看一个例子:
31415926 最左面那位数是3,如何得来?
取对数: lg(3.1415926 * 10^7) = lg(3.1415926) + 7
也就是说,一个整数取对数以后变为2部分,不妨设小数部分为A (0 <= A < 1),整数部分为B
所以,一个整数可以写成 10^A * 10^B
至于 10^B 是大家熟悉的 10000……
而 10^A 是什么样子的呢? 肯定是小于10的小数 (为什么呢,如果大于10了,B的值则加1)
那么 A 的整数部分就是我们要求的数
大致思路就是:对一个数x求对数,取出小数部分A,则10^A的整数部分就是x的最左面的那位数
进入本题:
x = 2^n
lg(x) = n * lg(2)
A = lg(x) - lg(x)的整数部分
10^A = ……
其实这道题卡的事精度问题,整数与小数来回转化肯定有精度损失 这里的A要加上1.0e-6
#include <stdio.h> #include <math.h> #define eps (1.0e-6) int f[10010][10]; int main() { int i, j, y; double A, x, s=log10(2); f[0][1]=1; for (i=1; i<=10000; i++) { for(j=1; j<10; j++) f[i][j] = f[i-1][j]; x = i * s; A = x - (int)x; y = (int) (pow(10, A)+eps); f[i][y]++; } while (scanf("%d",&y),y+1) { printf("%d", f[y][1]); for(i=2; i<10; i++) printf(" %d",f[y][i]); printf("/n"); } return 0; }