[codeforces1073E]Segment Sum

time limit per test : 1 second
memory limit per test : 256 megabytes

分数:2300
You are given two integers l l and r ( l r ) r (l≤r) . Your task is to calculate the sum of numbers from l l to r r (including l l and r r ) such that each number contains at most k different digits, and print this sum modulo 998244353 998244353 .

For example, if k = 1 k=1 then you have to calculate all numbers from l to r such that each number is formed using only one digit. For l = 10 l=10 , r = 50 r=50 the answer is 11 + 22 + 33 + 44 = 110 11+22+33+44=110 .

Input

The only line of the input contains three integers l , r l, r and k ( 1 l r < 1 0 18 , 1 k 10 ) k (1≤l≤r<10^{18},1≤k≤10) — the borders of the segment and the maximum number of different digits.

Output

Print one integer — the sum of numbers from l l to r r such that each number contains at most k k different digits, modulo 998244353 998244353

.
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 l l to r r which equals to 50 51 / 2 9 10 / 2 = 1230 50⋅51/2−9⋅10/2=1230 . This example also explained in the problem statement but for k = 1 k=1 .

For the second example the answer is just the sum of numbers from l l to r r which equals to 2345 2346 / 2 = 2750685 2345⋅2346/2=2750685 .

For the third example the answer is 101 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 121 + 122 + 131 + 133 + 141 + 144 + 151 = 2189 101+110+111+112+113+114+115+116+117+118+119+121+122+131+133+141+144+151=2189 .

题意:
给定l,r,k,询问[l,r]中所有x的总和,x是满足:组成x的所有数码的种类数不超过k。

题解:
数位dp
设dp(x)为 l = 1 , r = x l=1,r=x 的答案
f [ i ] [ S ] [ j ] [ l ] f[i][S][j][l] 表示第 i i 位, j j 表示生成的数字串是否小于 x x , l l 表示是否大于 0 0 的数字个数。
d [ i ] [ S ] [ j ] [ l ] d[i][S][j][l] 表示第 i i 位, j j 表示生成的数字串是否小于 x x , l l 表示是否大于 0 0 的数字之和。
然后就可以数位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;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/100707895