SP17247

题面

我的方法好像和大家都不一样诶,那我就写个题解吧。

约定:

[a,b] 为区间 [a,b] 中每个数的数字和的和,[a,b) 为区间 [a,b) 中每个数的数字和的和。

分析:

首先将区间问题转化为前缀和问题,即 [a,b]=[0,b][0,a1]=[0,b+1)[0,a)

也就是说我们只需要能求出任意的 [0,n]=[0,n+1) 就可以了。

下面考虑如何求 [0,n)

求解:

不难发现,如果我们把 n 的按每一位拆开,比如如果 n=4325,则显然有 [0,4325)=[0,4000)+[4000,4300)+[4300,4320)+[4320,4325)

形式化地说,如果令 n=i=0lgnai10i(aiN),则必然有:

[0,n)=i=0lgn[nj=0iai,nj=0i1ai)

(好像有点太形式化了)

我们考虑如何求 [43000,43200)

我们发现,只要预处理求出 {a},[0,10i)[0,i](0i9),然后按从例子中发现的规律,从高往低挨位处理,就可以快速求出 [0,n) 的值了。

代码:

代码中有更明确的计算方式,可能更好理解吧。

#include<bits/stdc++.h>
#define endl '\n'
#define rep(i, s, e) for(int i = s; i <= e; ++i)
#define per(i, s, e) for(int i = s; i >= e; --i)
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128_t i128;
typedef __uint128_t u128;
typedef pair<int, int> pii;
ll pw10[20], g[10], s0[20]; // pw10[i]: 10的i次幂,g[i]: [0,i]或[0,i+1),s0[i]: [0,10^i)
void init() {
    pw10[0] = 1;
    rep(i, 1, 15) pw10[i] = pw10[i - 1] * 10;
    rep(i, 1, 9) g[i] = g[i - 1] + i;
    s0[1] = 45;
    rep(i, 1, 15) s0[i] = s0[i - 1] * 10 + 45 * pw10[i - 1]; // [0,9]=45
}
ll calc(ll x) {
    ll dg[20] = {}, ans = 0, j = 0;
    while(x) {
        dg[j++] = x % 10;
        x /= 10;
    }
    ll s = 0;
    per(i, j, 1) { // 核心部分
        s += dg[i];
        ans += s * dg[i - 1] * pw10[i - 1];
        ans += dg[i - 1] * s0[i - 1];
        if(dg[i - 1]) ans += g[dg[i - 1] - 1] * pw10[i - 1];
    }
    return ans;
}
int main() {
#ifdef ONLINE_JUDGE
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
#endif
    init();
    int t; cin >> t;
    while(t--) {
        ll a, b; cin >> a >> b;
        cout << calc(b + 1) - calc(a) << endl;
    }
    return 0;
}
posted @   untitled0  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示