Codeforces Round #725 (Div. 3) F. Interesting Function (数学)
-
题意:从\(l\)每次加\(1\)加到\(r\),每次操作后贡献为每一位数字的改变数,问总贡献是多少
-
题解:这题问题在于处理\(9,19,29,...,89\)和\(99,199,...,899\),这样的会产生额外贡献的数,不难发现,$ 9,19,29,...,89$这些数,每10个数就会产生额外的2个贡献,以此类推,\(99,199,...,899\)这些数每100个数就会产生额外的3个贡献,所以我们就需要算出有多少个\(9,19,...,89\);\(99,199,...,899\);.......这样会产生额外贡献的数,不难推出除10,除100,除1000这样就可以算出数量,但是这样不行,比如100,我们除以10会得到10,但这10个有里面有一个是99,这个是不应该算的,所以我们在算下一层的时候减去多余的贡献即可.
-
代码:
#include <iostream> #include <iomanip> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #define ll long long #define db double #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; int gcd(int a,int b){return b?gcd(b,a%b):a;} int lcm(int a,int b){return a/gcd(a,b)*b;} int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #ifdef lr001 freopen("/Users/somnus/Desktop/data/in.txt","r",stdin); #endif #ifdef lr002 freopen("/Users/somnus/Desktop/data/out.txt","w",stdout); #endif int _; cin>>_; while(_--){ ll l,r; cin>>l>>r; ll res1=0; ll res2=0; ll cnt1=l/10; ll cnt2=r/10; int base=1; for(ll i=10;i<=1000000000;i=i*10){ base++; ll tmp=l/i; res1+=tmp*base; if(i!=10) res1-=tmp*(base-1); } base=1; for(ll i=10;i<=1000000000;i=i*10){ base++; ll tmp=r/i; res2+=tmp*base; if(i!=10) res2-=tmp*(base-1); } cout<<r-cnt2+res2-l+cnt1-res1<<'\n'; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮