codeforces 1073 E. Segment Sum(數位dp統計和)
阿新 • • 發佈:2018-11-16
題目連結:http://codeforces.com/problemset/problem/1073/E
思路:數位dp按位求貢獻算和
#include <cstdio> #include <cstdlib> #include <cstring> #include <bitset> #include <cmath> #include <cctype> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <queue> #include <map> #include <set> #include <sstream> #include <iomanip> using namespace std; typedef long long ll; typedef unsigned long long ull; const ll inff = 0x3f3f3f3f3f3f3f3f; #define FOR(i,a,b) for(int i(a);i<=(b);++i) #define FOL(i,a,b) for(int i(a);i>=(b);--i) #define REW(a,b) memset(a,b,sizeof(a)) #define inf int(0x3f3f3f3f) #define si(a) scanf("%d",&a) #define sl(a) scanf("%I64d",&a) #define sd(a) scanf("%lf",&a) #define ss(a) scanf("%s",a) #define mod ll(998244353) #define pb push_back #define eps 1e-6 #define lc d<<1 #define rc d<<1|1 #define Pll pair<ll,ll> #define P pair<int,int> #define pi acos(-1) ll a[20],n,m,k,b[20]; Pll dp[20][1028]; Pll dfs(int pos,int qw,bool zero,bool limit) { if(!pos) return Pll(1,0); if(!limit&&dp[pos][qw].second!=-1) return dp[pos][qw]; int up=limit?a[pos]:9; Pll res=Pll(0,0),tmp; FOR(i,0,up) { int zz=qw|((zero||i)<<i); if(__builtin_popcount(zz)>k) continue; tmp=dfs(pos-1,zz,zero||i,limit&&i==a[pos]); res.first=(res.first+tmp.first)%mod; res.second=(res.second+tmp.second+1ll*i*b[pos-1]%mod*tmp.first%mod)%mod;//tmp.first表示後面有多少個狀態滿足條件 } if(!limit) dp[pos][qw]=res; return res; } ll query(ll n) { a[0]=0; while(n) a[++a[0]]=n%10,n/=10; return dfs(a[0],0,0,1).second; } int main() { cin.tie(0); cout.tie(0); REW(dp,-1); b[0]=1;FOR(i,1,19) b[i]=b[i-1]*10ll%mod; sl(n),sl(m),sl(k); ll x=query(m); ll y=query(n-1); printf("%I64d\n",((x-y)%mod+mod)%mod); return 0; }