ABC379E 题解

ABC379E 题解

一道很好的题,开始还以为是高精度来着,但是发现不必要也不能用高精度,而是用一种技巧代替。

题意

You are given a string S of length N consisting of digits from 1 through 9.

For each pair of integers (i,j) (1ijN) , define f(i,j) as the value obtained by interpreting the substring of S from the ith through the jth character as a decimal integer. Find i=1Nj=iNf(i,j)

N2×105

分析

很明显的可以找出一个递推式子来 dp[i]=dp[i1]×10+i×a[i]

然后最后的答案就是所有 dp 的和,但是这样做是会爆掉的,因为 N 比较大。

所以写高精度吗?然而是会超时的。

Tirick

对于这种输出的整数位数特别多的题目,可以直接考虑对每一位拆开按贡献来统计,比方说这道题里面,每个数字对个位的贡献分别都是 i×ai ;前 n1 个数字对十位的贡献分别是 i×ai ......

所以我们可以想到做一个前缀和,然后从低位到高位模拟高精度就可以了。

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],dp[N],s[N];
int ans[N<<1],cnt;
signed main()
{
cin>>n;
for(int i=1;i<=n;++i)scanf("%1lld",&a[i]),a[i]=a[i]*i,s[i]=s[i-1]+a[i];
int tmp=0;
for(int i=n;i>=1;--i)
{
tmp+=s[i];
ans[++cnt]=tmp%10;
tmp/=10;
}
while(tmp)ans[++cnt]=tmp%10,tmp/=10;
for(int i=cnt;i;--i)cout<<ans[i];
return 0;
}

Extra

ABC233E 和这道题的思路很相似,可以做一下。

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int a[N],s[N],n=1;
int ans[N],cnt;
signed main()
{
while(scanf("%1lld",&a[n])!=EOF)s[n]=s[n-1]+a[n],n++;
n--;
int tmp=0;
int l=min(0ll,n-101);
for(int i=n;i>=1;--i)
{
tmp+=s[i]-s[l];
ans[++cnt]=tmp%10;
tmp/=10;
}
while(tmp)ans[++cnt]=tmp%10,tmp/=10;
for(int i=cnt;i>=1;--i)cout<<ans[i];
return 0;
}
posted @   Hanggoash  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
动态线条
动态线条end
点击右上角即可分享
微信分享提示