zoukankan      html  css  js  c++  java
  • [CF1073E]Segment Sum

    题目大意:给定$K,L,R$,求$[L,R]$之间最多不包含超过$K$种数字的数的和。

    题解:数位$DP$,令$f_{i,j}$为选到第$i$个数,已经用了的数字状态为$j$,令$nxt$为当前条件的后面的数,$f_{i,j}=sumlimits_{nxt}(d imes10^i+nxt)(d为当前这一位填的数)$,$f_{i,j}=d imes10^isum_{nxt}1+sum_{nxt}nxt$

    可以记录$sum nxt^0$和$sum nxt^1$转移即可

    卡点:

    C++ Code:

    #include <cstdio>
    const int mod = 998244353;
    int tot, num[20];
    long long k, l, r;
    inline void up(long long &a, long long b) {if ((a += b) >= mod) a -= mod;}
    
    struct node {
    	long long cnt, sum;
    } f[20][1 << 10];
    
    long long pw[20];
    node calc(int x, int lim, int S) {
    	if (!x) return (node) {1, 0};
    	if (!lim && ~f[x][S].cnt) return f[x][S];
    	node F = (node) {0, 0};
    	for (int i = lim ? num[x] : 9; ~i; i--) {
    		int nxt;
    		if (!S && !i) nxt = 0;
    		else nxt = S | 1 << i;
    		if (__builtin_popcount(nxt) > k) continue;
    		node tmp = calc(x - 1, lim && i == num[x], nxt);
    		up(F.cnt, tmp.cnt);
    		up(F.sum, (tmp.sum + tmp.cnt * pw[x - 1] % mod * i) % mod);
    	}
    	if (!lim) f[x][S] = F;
    	return F;
    }
    long long solve(long long x) {
    	tot = 0;
    	while (x) {
    		num[++tot] = x % 10;
    		x /= 10;
    	}
    	return calc(tot, 1, 0).sum;
    }
    int main() {
    	__builtin_memset(f, -1, sizeof f);
    	scanf("%lld%lld%lld", &l, &r, &k);
    	pw[0] = 1; for (int i = 1; i < 20; i++) pw[i] = pw[i - 1] * 10 % mod;
    	printf("%lld
    ", (solve(r) - solve(l - 1) + mod) % mod);
    	return 0;
    }
    

      

  • 相关阅读:
    MongoDB Projection
    MongoDB 删除文档
    MongoDB 更新文档
    MongoDB 删除文档
    MongoDB 查询文档
    MongoDB 插入文档
    MongoDB 数据类型
    MongoDB 删除集合
    MongoDB 创建集合
    MongoDB 删除数据库
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9910946.html
Copyright © 2011-2022 走看看