1. 程式人生 > >bzoj 1833 [ZJOI2010]count 數字計數

bzoj 1833 [ZJOI2010]count 數字計數

scanf fin using span i++ spa ++ pri color

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1833

數字計數模板。自己yy的做法。感覺挺好的。

前導0的數量只和位數有關。

註意pw裏的 ll 別寫成 int !!!為這個棄療,好幾天後才一眼看出,把它A了……

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=12;
ll l,r,s[N+5],c[N+5],ct,sum[15],nm[N+5
]; ll pw(int k) { ll mul=10,ret=1;//ll while(k) { if(k&1)ret*=mul; mul*=mul;k>>=1; } return ret; } int cal(ll a) { if(!a)return 1; int cnt=0; while(a)a/=10,cnt++; return cnt; } void init() { int cnt=cal(r); for(int i=1;i<=cnt;i++) s[i]
=s[i-1]*10+pw(i-1); for(int i=2;i<=cnt;i++) c[i]=pw(i-1)+c[i-1]; } int pre(ll a) { int cnt=cal(a); for(int i=1;i<=cnt;i++)nm[i]=a%10,a/=10; return cnt; } int main() { scanf("%lld%lld",&l,&r); init();ct=pre(r); for(int i=ct;i;i--) { for(int j=0
;j<=9;j++) sum[j]+=nm[i]*s[i-1]+(nm[i]>j)*pw(i-1);//nm[i]表示從0到nm[i]-1 sum[nm[i]]+=(r%pw(i-1))+1; } sum[0]-=c[ct]; if(l) { ct=pre(l-1); for(int i=ct;i;i--) { for(int j=0;j<=9;j++) sum[j]-=nm[i]*s[i-1]+(nm[i]>j)*pw(i-1);//這裏是+!(因為是-=) sum[nm[i]]-=((l-1)%pw(i-1))+1; } sum[0]+=c[ct]; } for(int i=0;i<=9;i++)printf("%lld ",sum[i]); return 0; }

bzoj 1833 [ZJOI2010]count 數字計數