标签:inline alc 参考 pac typedef main open 学习 space
初稿
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=30;
ll OddNormal[maxn],EvenNormal[maxn],OddOdd[maxn],EvenEven[maxn],normal[maxn];
int a[maxn],len;
ll five[maxn];
void init()
{
five[0]=1;for(int i=1;i<20;++i)five[i]=5*five[i-1];
OddNormal[0]=EvenNormal[0]=1;
for(int n=1;n<20;++n)
{
OddNormal[n]=EvenNormal[n]=0;
for(int i=2;i<=n/2*2;i=i+2)OddNormal[n]=OddNormal[n]+five[i]*EvenNormal[n-i];
for(int i=1;i<(n+1)/2*2;i=i+2)EvenNormal[n]=EvenNormal[n]+five[i]*OddNormal[n-i];
}
for(int n=1;n<20;++n)
{
OddOdd[n]=EvenEven[n]=0;
for(int i=2;i<=n/2*2;i=i+2)EvenEven[n]=EvenEven[n]+five[i]*OddNormal[n-i];
for(int i=1;i<(n+1)/2*2;i=i+2)OddOdd[n]=OddOdd[n]+five[i]*EvenNormal[n-i];
}
normal[1]=5;
for(int n=2;n<20;++n)
{
normal[n]=5*OddOdd[n-1]+4*EvenEven[n-1]+4*OddNormal[n-1];
normal[n]=normal[n]+normal[n-1];
}
}
inline int countodd(int x)
{
return x/2;
}
inline int counteven(int x)
{
if(x==0)return 0;
return (x-1)/2+1;
}
ll calc()
{
if(len==1)return counteven(a[1]+1);
ll ret=normal[len-1]+countodd(a[len])*OddOdd[len-1]+(counteven(a[len])-1)*(OddNormal[len-1]+EvenEven[len-1]);
int cnt=1;
for(int i=len-1;i>0;--i)
{
if(cnt&1)
{
if(a[i+1]&1)
{
if(i==1)ret=ret+countodd(a[1]+1);
else ret=ret+countodd(a[i])*(EvenNormal[i-1]+OddNormal[i-1]);
if(a[i]%2==0)break;
}
else
{
if(i==1)break;
ret=ret+countodd(a[i])*OddOdd[i-1]+counteven(a[i])*EvenNormal[i-1];
}
}
else
{
if(a[i+1]&1)
{
if(i==1)ret=ret+counteven(a[1]+1);
else ret=ret+countodd(a[i])*OddOdd[i-1]+counteven(a[i])*(OddNormal[i-1]+EvenEven[i-1]);
}
else
{
if(i==1)ret=ret+counteven(a[1]+1);
else ret=ret+counteven(a[i])*(OddNormal[i-1]+EvenEven[i-1]);
if(a[i]&1)break;
}
}
if(a[i]%2==a[i+1]%2)cnt++;
else cnt=1;
}
return ret;
}
int f(ll x)
{
len=0;
while(x)
{
a[++len]=x%10;
x=x/10;
}
return 0;
}
int main()
{
//freopen("Input.txt","r",stdin);
init();
ll l,r,ansl,ansr;
int t;scanf("%d",&t);
for(int Case=1;Case<=t;++Case)
{
scanf("%I64d%I64d",&l,&r);
ansl=ansr=0;
f(r);ansr=calc();
//printf("ansr=%I64d\n",ansr);
if(l==1)ansl=1;
else{f(l-1);ansl=calc();}
//printf("ansl=%I64d\n",ansl);
printf("Case #%d: %I64d\n",Case,ansr-ansl);
}
}
参考网上代码学习数位dp的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ms(s,a) memset(s,a,sizeof(s))
#define debug(x) cout<<"< "#x" = "<<x<<" >\n"
int len,a[20];
ll dp[20][20][2][2];//TODO
ll dfs(int pos,int cnt,bool odd,bool lim,bool zero)
{
if(!pos)return odd^(cnt&1);
if(!lim&&dp[pos][cnt][odd][zero]!=-1)return dp[pos][cnt][odd][zero];
ll ret=0;
int _max=lim?a[pos]:9;
for(int i=0;i<=_max;++i)
{
if(zero)
{
if(i==0)ret+=dfs(pos-1,1,0,0,1);
else ret+=dfs(pos-1,1,i&1,lim&&i==_max,0);
}
else
{
if(odd==(i&1))ret+=dfs(pos-1,cnt+1,i&1,lim&&i==_max,0);
else
{
if(odd==(cnt&1))continue;
ret+=dfs(pos-1,1,i&1,lim&&i==_max,0);
}
}
}
if(!lim)dp[pos][cnt][odd][zero]=ret;
return ret;
}
ll calc(ll x)
{
if(x==0)return 1;
len=0;
while(x)
{
a[++len]=x%10;
x/=10;
}
return dfs(len,0,0,1,1);//check it later!
}
int main()
{
//freopen("Input.txt","r",stdin);
ms(dp,-1);
int t;scanf("%d",&t);
ll l,r;
for(int Case=1;Case<=t;++Case)
{
scanf("%I64d%I64d",&l,&r);
printf("Case #%d: %I64d\n",Case,calc(r)-calc(l-1));
}
}
标签:inline alc 参考 pac typedef main open 学习 space
原文地址:https://www.cnblogs.com/maoruimas/p/9710774.html