如何有效地计算总和?

时间:2019-08-02 21:30:10

标签: optimization mathematical-optimization

给出一个整数n使得(1<=n<=10^18)

我们需要计算f(1)+f(2)+f(3)+f(4)+....+f(n)

f(x)表示为:-

x = 1112222333, 然后f(x)=1002000300

每当我们看到相同数字的连续子序列时,我们都将其替换为第一个数字,并将其后面的所有数字都清零。

形式上,f(x) = Sum over all (first element of the contiguous subsequence * 10^i ),其中i是特定连续子序列从左侧开始的第一个元素的索引。

f(x)=1*10^9 + 2*10^6 + 3*10^2 = 1002000300

在,x = 1112222333, 索引为'9'的元素:-1 等等...

我们遵循基于零的索引:-)

对于,x = 1234。 元素在索引'0':-4处,元素在索引-'1':3处,元素在索引'2':-2处,元素在索引3:-1处

如何计算f(1)+f(2)+f(3)+....+f(n)

我想生成一种算法,可以有效地计算此和。

2 个答案:

答案 0 :(得分:0)

要解决此问题,以一位数字开头并查看得出的总和可能会有所帮助。 我的意思是这样:

比方说,我们定义<code>F(k)=\sum_{x=1}^{10^k-1} f(x)</code> (click for the rendered version),那么我们有:

F(1)= 45                # =10*9/2 by Euler's sum formula
F(2)= F(1)*9 + F(1)*100 # F(1)*9 is the part that comes from the last digit
                        # because for each of the 10 possible digits in the
                        # first position, we have 9 digits in the last 
                        # because both can't be equal and so one out of ten
                        # becomse zero. F(1)*100 comes from the leading digit 
                        # which is multiplied by 100 (10 because we add the
                        # second digit and another factor of 10 because we 
                        # get the digit ten times in that position)

如果您现在继续使用此方案,一般而言,k>=1会得到

F(k+1)= F(k)*100+10^(k-1)*45*9

其余的可能很简单。

您能告诉我,这是哪个Hackerrank任务吗?我猜欧拉计画的一项任务对吗?

答案 1 :(得分:0)

没有什么可计算的。

乘以数组od编号中的每个位置将得到相同的数字。

所以您要做的就是以重复数字0结束

IE让我们以伪代码填充数组中的一些静态值

$As[1]='0'
$As[2]='00'
$As[3]='000' 
...etc 
$As[18]='000000000000000000'```

these are the "results" of 10^index

Given a value n of `1234`

```1&000 + 2&00 +3 & 0 + 4```

Results in `1234`

So, if you are putting this on a chip, then probably your most efficient method is to do a bitwise XOR between each register and the next up the line as a single operation

Then you will have 0s in all the spots you care about, and just retrive the values in the registers with a 1


In code, I think it would be most efficient to do the following

```$n = arbitrary value 11223334
$x=$n*10
$zeros=($x-$n)/10```



Okay yeah we can just do bit shifting to get a value like 100200300400 etc.