B - Segment Sum CodeForces - 1073E

B - Segment Sum

 CodeForces - 1073E 

You are given two integers ll and rr (l≤rl≤r). Your task is to calculate the sum of numbers from ll to rr (including ll and rr) such that each number contains at most kkdifferent digits, and print this sum modulo 998244353998244353.

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

Input

The only line of the input contains three integers ll, rr and kk (1≤l≤r<1018,1≤k≤101≤l≤r<1018,1≤k≤10) — the borders of the segment and the maximum number of different digits.

Output

Print one integer — the sum of numbers from ll to rr such that each number contains at most kk different digits, modulo 998244353998244353.

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 ll to rr which equals to 50⋅512−9⋅102=123050⋅512−9⋅102=1230. This example also explained in the problem statement but for k=1k=1.

For the second example the answer is just the sum of numbers from ll to rr which equals to 2345⋅23462=27506852345⋅23462=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

题目大意:

给定一个区间,再给定一个不重复值k,要求给出,这个区间内

满足每个数上的各个位数的不同次数不能超过k 的数字的加和

思路:

数位dp求解

首先使用数位dp,再用一个state状态表示某个数是否出现过,加上一个bool表示是否是前导0,返回一个node,表示有几个数以及目前当前位的总和是多少,每一位的贡献可以通过数的个数计算出来,然后总和是可减的,求出0-r的总和与0-l-1的总和,减一下即可。

代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
typedef long long ll; 
using namespace std;
ll  A,B;
int K;
const ll mod = 998244353;
struct node{
	ll num;
	ll sum;
	node(){
		num=-1;sum=0;
	}
	node(ll x,ll y):num(x),sum(y){};
};
node dp[20][1100];
int digit[20];
int stanum[1100];
ll pow_[25];

node dfs(int pos,int state,bool lead,bool limit){
	if(pos<=-1) return node(1,0);
	if(!lead &&!limit && dp[pos][state].num!=-1) return dp[pos][state];
	int up = limit?digit[pos]:9;
	node ans(0,0);
	
	for(int i=0;i<=up;i++){
		node next(0,0);
		if( !((state>>i)&1) && !(lead && i==0)) {
			int temp_state = state|1<<i;
			if(stanum[temp_state]>K) continue;
	
			next= dfs(pos-1,temp_state,lead&& i==0,limit && i == up);
		}else{
			next= dfs(pos-1,state, lead&& i==0,limit && i == up);
		}
		ans.num+=next.num%mod;
		ans.num%=mod;
		ans.sum+=(next.sum+pow_[pos]*i%mod*next.num%mod)%mod;
		ans.sum%=mod;
	}
	
	if(!lead &&!limit) dp[pos][state] = ans;
	return ans;
}

ll solve(ll x){
	int pos =0;
	while(x>0){
		digit[pos++] = x%10;
		x/=10;
	}
	node res = dfs(pos-1,0,true,true);
	return res.sum;
}

int main(){
	memset(stanum,0,sizeof(stanum));
	pow_[0] =1;
	for(int i=1;i<=20;i++) pow_[i] = pow_[i-1]*10%mod;
	stanum[0] = 0;
	stanum[1] = 1;
	for(int i=2;i<1100;i++){
		stanum[i] = stanum[i-(i&-i)]+1;
	}
	
	scanf("%lld %lld %d",&A,&B,&K);
	ll res1 = solve(B); 
	ll res2 = solve(A-1);
	ll res = res1 - res2;
	printf("%lld\n",(res%mod+mod)%mod);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Willen_/article/details/86776000