time limit per test : 1 second
memory limit per test : 256 megabytes
分数:2300
You are given two integers
and
. Your task is to calculate the sum of numbers from
to
(including
and
) such that each number contains at most k different digits, and print this sum modulo
.
For example, if then you have to calculate all numbers from l to r such that each number is formed using only one digit. For , the answer is .
Input
The only line of the input contains three integers and — the borders of the segment and the maximum number of different digits.
Output
Print one integer — the sum of numbers from to such that each number contains at most different digits, modulo
.
Examples
Input
10 50 2
Output
1230
Input
1 2345 10
Output
2750685
Input
101 154 2
Output
2189
Note
For the first example the answer is just the sum of numbers from to which equals to . This example also explained in the problem statement but for .
For the second example the answer is just the sum of numbers from to which equals to .
For the third example the answer is .
题意:
给定l,r,k,询问[l,r]中所有x的总和,x是满足:组成x的所有数码的种类数不超过k。
题解:
数位dp
设dp(x)为
的答案
表示第
位,
表示生成的数字串是否小于
,
表示是否大于
的数字个数。
表示第
位,
表示生成的数字串是否小于
,
表示是否大于
的数字之和。
然后就可以数位dp交替更新了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MOD=998244353LL;
int Cuming(int S){
int c=0;
for(int i=0;i<10;i++){
if(S&1)c++;
S>>=1;
}
return c;
}
ll l,r;
int k;
int len,sp[24];
ll f[24][1<<11][2][2],g[24][1<<11][2][2];
ll calc(ll x){
memset(sp,0,sizeof(sp));
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
ll ret=0;
len=0;
f[1][0][0][0]=1;
if(x==0)sp[++len]=0;
while(x){
sp[++len]=x%10;
x/=10;
}
reverse(sp+1,sp+len+1);
for(int i=1;i<=len;i++){
for(int j=0;j<2;j++){
for(int l=0;l<2;l++){
for(int S=0;S<(1<<10);S++){
int Lim;
if(j)Lim=9;
else Lim=sp[i];
if(!f[i][S][j][l])continue;
for(int now=0;now<=Lim;now++){
int nS;
if(l||now)nS=(S|(1<<now));
else nS=S;
f[i+1][nS][j||(now<Lim)][l||now]+=f[i][S][j][l];
f[i+1][nS][j||(now<Lim)][l||now]%=MOD;
g[i+1][nS][j||(now<Lim)][l||now]+=(((g[i][S][j][l]*10)%MOD)+(now*f[i][S][j][l])%MOD)%MOD;
g[i+1][nS][j||(now<Lim)][l||now]%=MOD;
}
}
}
}
}
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int l=0;l<(1<<10);l++){
if(Cuming(l)<=k){
ret+=g[len+1][l][i][j];
ret%=MOD;
}
}
}
}
return ret;
}
int main(){
scanf("%lld%lld%d",&l,&r,&k);
ll ansl=calc(l-1);
ll ansr=calc(r);
printf("%lld\n",(ansr-ansl+MOD)%MOD);
return 0;
}