SP10606题解
本文同步更新于博客园
题目描述
一个数被称为是平衡的数,当且仅当对于所有出现过的数位,每个偶数出现奇数次,每个奇数出现偶数次。给定
题解
平衡数与数的大小无关,并且我们要统计一个区间内符合条件的数的个数,不难想到用数位 dp。又因为我们要统计数字出现的次数,所以需要状态压缩。
我们用
接下来,我们传五个参数
注意到本题的内存限制是
Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t,len,a[20];
ll l,r,f[20][1024][1024];
ll check(int x,int y)
{
for(int i=0;i<=9;i++)
{
if(y&(1<<i))
{
if((i&1)^(x&(1<<i))==0)
return 0;
}
}
return 1;
}
ll dfs(int k,int x,int y,int p,int q)
{
if(!k)
return check(x,y);
if(!p&&!q&&f[k][x][y]!=-1)
return f[k][x][y];
int z=q?a[k]:9,w;
ll res=0;
for(int i=0;i<=z;i++)
{
w=p&&!i;
res+=dfs(k-1,w?0:x^(1<<i),w?0:y|(1<<i),w,q&&(i==z));
}
if(!p&&!q)
f[k][x][y]=res;
return res;
}
ll divide(ll x)
{
len=0;
while(x)
{
a[++len]=x%10;
x/=10;
}
return dfs(len,0,0,1,1);
}
int main()
{
memset(f,-1,sizeof(f));
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",divide(r)-divide(l-1));
}
return 0;
}