題目
首先咱們能夠經過經典容斥轉化爲計算\([1,x]\)的答案。
如今咱們考慮一個數的個位對答案的貢獻。
每作一次操做都會讓個位加上十位而後取模,直到只有個位爲止。
咱們發現這個過程當中,個位數前的係數永遠都是\(1\),也就是個位數對答案的貢獻係數爲\(1\)。
這意味着咱們對於一個固定的只有個位沒肯定的數,咱們枚舉其個位\(0\sim9\),其答案也是\(0\sim9\),因此咱們能夠直接求出\([1,\lfloor\frac n{10}\rfloor*10-1]\)的答案爲\(\lfloor\frac n{10}\rfloor*45\)。
而後剩下\(n\mod10+1\)個數,直接計算很不優秀。
咱們先暴力計算\(t=f(\lfloor\frac n{10}\rfloor)\),那麼\(f(\lfloor\frac n{10}\rfloor)+i=t+i(i\in[0,9])\),這樣只用暴力算一次,很是優秀。c++
#include<bits/stdc++.h> #define ll long long using namespace std; int a[19]; int f(ll x) { int len=0,i; while(x) a[++len]=x%10,x/=10; while(len^1) { for(i=1;i<len;++i) a[i]=(a[i]+a[i+1])%10; for(--len;!a[len]&&len^1;--len); } return a[len]; } ll cal(ll x) { if(x<10) return x*(x+1)/2; ll s=x/10*45;int o=x%10,i,t=f(x/10*10); for(i=0;i<=o;++i) s+=(t+i)%10; return s; } int main() { int T;ll l,r; for(scanf("%d",&T);T;--T) scanf("%lld%lld",&l,&r),printf("%lld\n",cal(r)-cal(l-1)); }