数位dp第一弹
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<sstream>
#include<string>
#include<bitset>
using namespace std;
typedef long long LL;
const LL LINF = (1LL <<63);
const int INF = 1 << 31;
const int NS = 500010;
const int MS = 19;
const int MOD = 1000000007;
LL p10[22];
void prepare()
{
p10[0] = 1;
for(int i = 1; i < 22; i++)
{
p10[i] = p10[i - 1] * 10;
}
}
LL getSum1(int prelen, int suflen)//prelen >= 1, suflen >= 1;
{
LL ans = 0;
// if(suflen <= 0) return 0;
if((prelen + suflen) & 1)
{
ans = -(p10[suflen] / 2);
}
else
{
if(suflen & 1)
{
ans = -(p10[suflen] * 9 / 2);
}
}
return ans;
}
LL checkSum1(int prelen, int suflen)//suflen >= 1;
{
LL ans = 0;
int flag = 1;
LL lim = p10[suflen];
for(LL i = 0; i < lim; i++)
{
if(prelen & 1) flag = -flag;
for(int j = suflen - 1; j >= 0; j--)
{
int v = (i / p10[j]) % 10;
ans += flag * v;
flag = - flag;
}
}
return ans;
}
LL getSum2(LL prefix, int suflen)//prefix >= 1, suflen >= 1
{
LL presum = 0;
int prelen = 0;
int flag = 1;
for(LL x = prefix; x > 0; x /= 10)
{
prelen ++;
presum += (x % 10) * flag;
flag = - flag;
}
presum *= -flag;
LL ans = getSum1(prelen, suflen);
if(0 == ((prelen + suflen) & 1) )
{
presum *= p10[suflen];
ans += presum;
}
return ans;
}
LL getSum3(LL n)
{
LL ans = 0;
if(n < 10)
{
for(int i = 1; i <= n; i++)
{
ans += i * (0 == (i&1)? -1 : 1);
}
return ans;
}
int bitv[22];
int nlen = 0;
for(LL x = n; x > 0; x /= 10)
{
bitv[++nlen] = x % 10;
}
//计算 1 ~ 9999999(nlen 个 9)
ans = 5;
for(int suflen = 1; suflen < nlen - 1; suflen ++)
{
for(LL prefix = 1; prefix < 10; prefix ++)
{
ans -= getSum2(prefix, suflen);
}
}
LL prefix = 0;
LL presum = 0;
int flag = 1;
for(int pos = nlen; pos > 1; pos --)
{
for(int i = 0; i < bitv[pos]; i++)
{
if(0 != prefix)
{
ans -= getSum2(prefix, pos - 1);
}
prefix ++;
}
prefix *= 10;
presum += flag * bitv[pos];
flag = - flag;
}
int restnum = bitv[1] + 1;
if(nlen & 1)
{
if(restnum & 1)
{
ans -= presum;
ans -= bitv[1];
}
ans += restnum / 2;
}
else
{
ans -= presum * restnum;
ans += restnum * bitv[1] / 2;
}
return ans;
}
LL recoder, mark;
void cal(LL x)
{
int bitv[22], len = 0;
for(LL t = x; t > 0; t /= 10)
{
bitv[len++] = t % 10;
}
for(int pos = len - 1; pos >= 0; pos --)
{
recoder += mark * bitv[pos];
mark = -mark;
}
}
int main()
{
prepare();
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
// mark = 1; recoder = 0;
// for(LL i = 1; i < 10000000; i ++)
// {
// cal(i);
//
// if(i >= 101)
// {
// LL ans = getSum3(i);
// if(ans != recoder)
// {
// printf("i = %I64d recoder = %I64d ans = %I64d\n", i, recoder, ans);
// break;
// }
// }
// }
LL n;
while(~scanf("%lld", &n))
{
if(0 == n) break;
printf("%lld\n", getSum3(n));
}
return 0;
}