zoukankan      html  css  js  c++  java
  • codeforces 1073E

    题解:

    考虑数位DP,状压出现过的数字集合S,f ( l , x , S , pz , lim )表示到第 l 位,数字为x, 数字集合为S ,是否为前导0,是否贴上界

    然后同时定义g为该状态下的数字和,利用 10^(l-1) * f(l , x, S, pz, lim)计算该位的贡献,然后加上所有后继的g就行了

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const ll mod = 998244353;
     5 ll l,r;
     6 int k;
     7 int num[22],cnt;
     8 ll f[22][10][1050][2][2],g[22][10][1050][2][2];
     9 bool vis[22][10][1050][2][2];
    10 ll fastpow(ll a,ll p)
    11 {
    12     ll ans=1;
    13     while(p)
    14     {
    15         if(p&1)ans=ans*a%mod;
    16         a=a*a%mod;p>>=1;
    17     }
    18     return ans;
    19 }
    20 void dfs(int l,int x,int S,bool pz,bool lim)
    21 {
    22     if(vis[l][x][S][pz][lim])return;
    23     vis[l][x][S][pz][lim]=1;
    24     int t=0;
    25     for(int i=0;i<10;++i)if(S&(1<<i))t++;
    26     if(t>k)return;
    27     if(l==1)
    28     {
    29         f[l][x][S][pz][lim]=1,g[l][x][S][pz][lim]=x;
    30         return;
    31     }
    32     int up=(lim)?num[l-1]:9;
    33     for(int i=0;i<=up;++i)
    34     {
    35         dfs(l-1,i,(pz&(!i))?0:(S|(1<<i)),pz&(!i),lim&(i==num[l-1]));
    36         f[l][x][S][pz][lim]=(f[l][x][S][pz][lim]+f[l-1][i][(pz&(!i))?0:(S|(1<<i))][pz&(!i)][lim&(i==num[l-1])])%mod;
    37         g[l][x][S][pz][lim]=(g[l][x][S][pz][lim]+g[l-1][i][(pz&(!i))?0:(S|(1<<i))][pz&(!i)][lim&(i==num[l-1])])%mod;
    38     }
    39     g[l][x][S][pz][lim]=(g[l][x][S][pz][lim]+f[l][x][S][pz][lim]*x%mod*fastpow(10,l-1)%mod)%mod;
    40 }
    41 ll solve(ll n)
    42 {
    43     if(!n)return 0; 
    44     memset(num,0,sizeof(num));
    45     memset(f,0,sizeof(f));
    46     memset(g,0,sizeof(g));
    47     memset(vis,0,sizeof(vis));
    48     cnt=0;
    49     ll x=n;
    50     while(x)
    51     {
    52         num[++cnt]=x%10;
    53         x/=10;
    54     }
    55     ll ans=0;
    56     for(int i=0;i<=num[cnt];++i)
    57     {
    58         dfs(cnt,i,(i==0)?0:(1<<i),(i==0),(i==num[cnt]));
    59         ans=(ans+g[cnt][i][(i==0)?0:(1<<i)][(i==0)][(i==num[cnt])])%mod;
    60     }
    61     return ans;
    62 }
    63 int main()
    64 {
    65     scanf("%I64d%I64d%d",&l,&r,&k);
    66     printf("%I64d
    ",(solve(r)-solve(l-1)+mod)%mod);
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    python实现测试中常用的脚本(待完善)
    python使用mysql数据库(虫师)
    jQuery中动画animate(上)
    jQuery事件对象的属性和方法
    扩展欧几里得算法详解
    jQuery事件对象的作用(利用冒泡事件优化)
    卸载事件off()方法
    on()的高级用法
    三种快速排序以及快速排序的优化
    on()的多事件绑定
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10612406.html
Copyright © 2011-2022 走看看