高逸涵的论文《数位计数问题解法研究》第一个例题 讲解的很详细 也是数位统计的入门训练吧
题意:输入一个数N 输出从1到N每个数的每位(十进制)以+ - 循环处理的和
For example, if N=12 then+1 -2 +3 -4 +5 -6 +7 -8 +9 -1+0 -1+1 -1+2 = 5
按论文的的想法分奇偶进行统计即可
#include<iostream>
using namespace std;
#define N 16
typedef long long LL;
LL digital[N];
LL zero[N];
int special[10];
int add[10];
int bit[N+1];
int len;
void init()
{
for(int i=1;i<10;i++)
{
add[i]+=add[i-1]+i;
if(i&1)
special[i]=special[i-1]+i;
else
special[i]=special[i-1]-i;
}
digital[1]=special[9];
zero[0]=1;
for(int i=1;i<N;i++)
zero[i]=zero[i-1]*10;
for(int i=2;i<N;i++)
{
if(i&1)
digital[i]=digital[i-1]+9*zero[i-1]/2;
else
digital[i]=digital[i-1]-zero[i-2]*add[9];
}
}
LL cal(LL n) //不小心写出int cal(LL n) wa了很久很久....
{
len=0;
LL s=n;
while(s)
{
bit[++len]=s%10;
s/=10;
}
LL ans=digital[len-1];
if(len&1)
{
if(n&1)
ans+=(n-zero[len-1]+1)/2;
else
{
ans+=(n-zero[len-1])/2;
for(int i=len;i>=1;i--)
{
if(i&1)
ans-=bit[i];
else
ans+=bit[i];
}
}
}
else
{
for(int i=len;i>=1;i--)
{
if(bit[i])
{
int f;
if(i!=len)
f=1;
else
f=0;
if(i&1)
ans+=add[bit[i]-1]*zero[i-1]+bit[i]*(n%zero[i-1]+1);
else
ans+=-add[bit[i]-1]*zero[i-1]+(bit[i]-1+f)*add[9]*zero[i-2]-bit[i]*(n%zero[i-1]+1);
}
}
}
return ans;
}
int main()
{
init();
LL n;
while(cin>>n&&n)
{
if(n<10)
cout<<special[n]<<endl;
else
cout<<cal(n)<<endl;
}
return 0;
}