• 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 }
  • 相关阅读:
    XHTML基础问答-给初学者
    动态改变表格的行数列数(添加表格)
    记录的添加,修改,删除等操作,??
    数据绑定
    优秀ASP.NET程序员修炼之路
    关于Command的ExecuteNonQuery(),ExecuteScalar(),ExecuteReader方法的区别
    MyEclipse7.5注册
    实用JavaScript代码库
    解决数据库录入中文数据乱码问题
    Oracle占用8080端口问题的解决
  • 原文地址:https://www.cnblogs.com/Menhera/p/9901921.html
Copyright © 2020-2023  润新知