Codeforces1073E Segment Sum 数位DP
Posted menhera
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1073E Segment Sum 数位DP相关的知识,希望对你有一定的参考价值。
题目分析:
裸的数位DP,注意细节。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int mod = 998244353; 5 int k; 6 7 int dp[25][1024],sz[25][1024],cnt[25][1024]; 8 int pw10[25],hp[25],num; 9 10 int dfs(int now,int lst){ 11 if(now == 0) return 0; 12 int ans = 0; 13 for(int i=0;i<hp[now];i++){ 14 for(int j=0;j<(1<<10);j++){ 15 int pp = (lst==0&&i==0?0:(1<<i)); 16 int z = __builtin_popcount(j|pp|lst); 17 if(z > k) continue; 18 ans += 1ll*sz[now-1][j]*pw10[now-1]%mod*i%mod; ans %= mod; 19 ans += dp[now-1][j]; ans %= mod; 20 } 21 } 22 if(now == num){ 23 for(int i=1;i<num-1;i++){ 24 for(int j=0;j<(1<<10);j++){ 25 int z = __builtin_popcount(j); 26 if(z > k) continue; 27 z = __builtin_popcount(j|1); 28 if(z <= k) continue; 29 ans += dp[i][j]; ans %= mod; 30 } 31 } 32 } 33 for(int i=0;i<(1<<10);i++){ 34 int z = __builtin_popcount(i|(1<<hp[now])|lst); 35 if(z > k) continue; 36 ans += 1ll*cnt[now-1][i]*pw10[now-1]%mod*hp[now]%mod; 37 ans %= mod; 38 } 39 ans += dfs(now-1,lst|(1<<hp[now])); 40 ans %= mod; 41 return ans; 42 } 43 44 int solve(long long now){ 45 num = 0; 46 memset(cnt,0,sizeof(cnt));cnt[0][0] = 1; 47 while(now){hp[++num] = now%10;now /= 10;} 48 for(int i=1;i<=num;i++){ 49 for(int j=0;j<hp[i];j++){ 50 for(int k=0;k<(1<<10);k++){ 51 cnt[i][k|(1<<j)] += sz[i-1][k]; 52 cnt[i][k|(1<<j)] %= mod; 53 } 54 } 55 for(int k=0;k<(1<<10);k++){ 56 cnt[i][k|(1<<hp[i])] += cnt[i-1][k]; 57 cnt[i][k|(1<<hp[i])] %= mod; 58 } 59 } 60 return dfs(num,0); 61 } 62 63 int main(){ 64 long long l,r; 65 cin >>l >> r >> k; 66 sz[0][0] = 1;pw10[0] = 1; 67 for(int i=1;i<=20;i++) pw10[i] = 1ll*pw10[i-1]*10%mod; 68 for(int i=1;i<=20;i++){ 69 for(int f = 1;f<=9;f++){ 70 for(int j=0;j<(1<<10);j++){ 71 sz[i][j|(1<<f)] += sz[i-1][j]; sz[i][j|(1<<f)]%=mod; 72 dp[i][j|(1<<f)] += dp[i-1][j]; dp[i][j|(1<<f)] %= mod; 73 dp[i][j|(1<<f)] += 1ll*sz[i-1][j]*pw10[i-1]%mod*f%mod; 74 dp[i][j|(1<<f)] %= mod; 75 for(int k=0;k<i-1;k++){ 76 sz[i][j|(1<<f)|1] += sz[k][j]; sz[i][j|(1<<f)|1]%=mod; 77 dp[i][j|(1<<f)|1] += dp[k][j]; dp[i][j|(1<<f)|1]%=mod; 78 dp[i][j|(1<<f)|1] += 1ll*sz[k][j]*pw10[i-1]*f%mod; 79 dp[i][j|(1<<f)|1] %= mod; 80 } 81 } 82 } 83 } 84 for(int i=1;i<=20;i++){ 85 for(int j=0;j<(1<<10);j++){ 86 sz[i][j|1] += sz[i-1][j]; 87 dp[i][j|1] += dp[i-1][j]; 88 sz[i][j|1] %= mod; dp[i][j|1] %= mod; 89 } 90 } 91 long long ans = solve(r)-solve(l-1); 92 ans+=mod; ans %= mod; 93 cout<<ans<<endl; 94 return 0; 95 }
以上是关于Codeforces1073E Segment Sum 数位DP的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 48 (Rated for Div. 2) B Segment Occurrences
Educational Codeforces Round 48 (Rated for Div. 2) B. Segment Occurrences(数组前缀和防TLE)