首页 > 其他分享 >【总结】2023-03-01 Σ[k=0..10^100]floor(X/10^k)

【总结】2023-03-01 Σ[k=0..10^100]floor(X/10^k)

时间:2023-03-03 18:57:29浏览次数:55  
标签:10 01 千位 03 int sum len ans

Σ[k=0..10 ^ 100]floor(X/10 ^ k)

题意

给定一个整数 \(x\),求 \(\sum\limits_{k=0}^{10^{100}} \lfloor \frac{x}{10^k} \rfloor\)。

数据范围

  • \(1 \leqslant x \leqslant 10^{500000}\)

思路

看数据范围就知道:long long 存不下,需要高精度。

直接高精度会达到 \(O(|x|^2)\),也是过不了的。

又要推一下了,画个草图看看。

可以发现,在样例1中:

  • 个位、十位、百位、千位都可以对答案的个位做出贡献。
  • 十位、百位、千位都可以对答案的十位做出贡献。
  • 百位、千位都可以对答案的百位做出贡献。
  • 千位可以对答案的千位做出贡献。

再稍微推一推,就可以发现:

  • 若 \(x = \overline{a_1\ a_2\ a_3\ \dots \ a_n}\)
    • 那么答案就是 \(\sum\limits_{i=1}^{n} (\sum\limits_{j=1}^{n-i+1} a_i \times 10^i)\)

复杂度

  • 时间:\(O(|x|)\)
  • 空间:\(O(|x|)\)

Code

点击查看代码
#include <iostream>
#include <vector>
#include <string>

using namespace std;

const int N = 6e5 + 10;

string s; // x 太大了,得用字符串
int n, ans[N], sum, lans = 1;

void P () {
  int len = n + 1;
  for (int i = 0; i < len; i++) { // 处理进位
    ans[i + 1] += ans[i] / 10;
    ans[i] %= 10;
  }
  while (len > 1 && !ans[len - 1]) { // 处理前导零
    len--;
  }
  lans = len;
}

void Cout () {
  for (int i = lans - 1; i >= 0; i--) { // 从最高位开始输出
    cout << ans[i];
  }
}

int main(){
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> s;
  n = s.size();
  for (int i = 0; i < n; i++) {
    sum += s[i] - '0'; // 前缀和思想
    ans[n - i - 1] = sum; // 去处理答案第 n - i - 1 位(第0位为个位)
  }
  P(); // 最后再处理进位
  Cout();
  return 0;
}

标签:10,01,千位,03,int,sum,len,ans
From: https://www.cnblogs.com/Luogu724052/p/17176520.html

相关文章