丛林木马
时间限制:1秒 空间限制:256M
网页链接
牛客tracker
牛客tracker & 每日一题,完成每日打卡,即可获得牛币。获得相应数量的牛币,能在【牛币兑换中心】,换取相应奖品!助力每日有题做,丰盈牛币日益多!
题目描述
朽木裂,雷霆惊,丛林木马怒冲天。
众所周知,如果给你两个数a , b a,ba,b要你计算a × b = c a×b=ca×b=c的值,你就知道要这么做:把每一位相乘并且乘上它们的10 k 10k10k然后相加,其中k kk表示对应数位的幂次。
有一次,可怜的Z M ZMZM不小心把“相乘”中的所有乘法运算都算成了加法,她想让你帮忙算算,这样算出来的结果是多少?
输入描述:
全文第一行输入一个整数T ( 1 ≤ T ≤ 10 5 ) T(1≤T≤10^5)T(1≤T≤105),表示数据组数。
每行输入两个正整数a , b ( 1 ≤ a , b ≤ 10 10 5 ) a,b(1≤a,b≤10^{10^5})a,b(1≤a,b≤10105),表示两个因数。
数据保证∑ ∣ a ∣ , ∑ ∣ b ∣ ≤ 10 6 ∑∣a∣,∑∣b∣≤10^6∑∣a∣,∑∣b∣≤106,其中∣ a ∣ , ∣ b ∣ ∣a∣,∣b∣∣a∣,∣b∣表示两个数的位数。
输出描述:
每行输出一个数表示你计算出的答案,为方便输出,你只需要输出最终结果对998244353 998244353998244353取模后的值即可。
示例1
输入:
4 12 13 123 456 1314520 5201314 998244353 100000007输出:
50 1737 45610838 900000063说明:
对于样例 #1:
把每一位拆开并且相加,每一个和统计出来:20 + 13 + 12 + 5 = 50 20+13+12+5=5020+13+12+5=50。
对于样例 #2:
它们的和是:500 + 150 + 106 + 420 + 70 + 26 + 403 + 53 + 9 = 1737 500+150+106+420+70+26+403+53+9=1737500+150+106+420+70+26+403+53+9=1737。
解题思路
本题核心是数学公式化简+大数模运算,破解错误乘法的计算规则。通过展开数位计算式推导得出:将乘法替换为加法后的总结果 = 数字a aa的模值× ××b bb的位数+ ++数字b bb的模值× ××a aa的位数,最终对998244353 998244353998244353取模。输入为超长数字字符串(最长1 e 5 1e51e5位),逐位遍历计算大数的模值,同时统计数字长度。针对1 e 5 1e51e5组测试数据、总长度1 e 6 1e61e6的约束,采用快速输入优化,全程线性遍历处理字符串,无复杂运算,时间复杂度为O ( ∑ ∣ a ∣ + ∑ ∣ b ∣ ) O(\sum |a|+\sum |b|)O(∑∣a∣+∑∣b∣),高效完成计算。
总结
核心逻辑:利用数学推导将复杂数位求和化简为简单公式,规避暴力枚举。
关键操作:字符串读取超长数字、逐位取模、统计位数、公式计算。
效率保障:线性处理数据+快速I O IOIO,完美适配大数据量与时间空间限制。
代码内容
#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;typedefvector<vector<ll>>vvt;typedefpair<ll,ll>pll;constll N=1e3+10;constll p=1e9+7;constll INF=1e18;constll M=1e6+10;constll mod=998244353;voidsolve(){string a,b;cin>>a>>b;ll la=a.size();ll lb=b.size();ll x=0,y=0;for(ll i=0;i<la;i++){x=x*10+(a[i]-'0');x%=mod;}for(ll i=0;i<lb;i++){y=y*10+(b[i]-'0');y%=mod;}cout<<((x%mod*lb)%mod+(y%mod*la)%mod)%mod<<'\n';}intmain(){ll t;cin>>t;while(t--)solve();return0;}