Educational Codeforces Round 53 (Rated for Div. 2) E. Segment Sum

https://codeforces.com/contest/1073/problem/E

题意

求出l到r之间的符合要求的数之和,结果取模998244353

要求:组成数的数位所用的数字种类不超过k种

思路

这题一看就是个数位dp的模板题,但是由于以前没有完全理解数位dp加上xjb套模版,导致样例都没算出来

  • 一开始这样定义状态

    dp[i][j] 代表第cnt~i(高位到低位)位,cnt~i状态为j的总和

  • 一直记录当前数字的数值,到边界的时候返回加到答案中,但是由于这样定义状态会导致一个状态对应多个数,但是他只能累加字典序最小的数到答案中,所以会使得有的数并没有被计算
  • 仔细分析一波,回归dp本身,应该找到一个子状态,使得后面的状态可以通过前面的状态计算得到(转移),其实只需要改一下定义

    dp[i][j] 代表0~i(低位到高位),cnt~i+1状态为j的总和sum和数字个数num(dp两个东西)

    在第i步选择第i位的数字

  • 其实就是转换一下计算方法,比如0~9可以加在数字1后,组成10~19,转化为公式\(10^{i-1}*dp[i-1][j|(1<<digit)].num*digit\)
  • 转移为:\(dp[i][j]=\sum_{digit=0}^{9}(dp[i][j].sum+10^{i-1}*dp[i-1][j|(1<<digit)].num*digit)\)

关于数位dp

  • 对于每个数求出的是小于这个数的所有满足条件的数(前缀和)

    • 将一个数当成字符串,然后从高位往低位看,lead看前导0是否对计数产生影响
    • 通常定义状态可以理解为

      dp[i][j] 代表0~i(低位到高位),cnt~i+1状态为j的计数

  • 关于lead和limit,可以放在数组下标,也可以在函数里特判

附上一个lead和limit在函数中特判的板子

#include<bits/stdc++.h>
#define ll long long
#define P 998244353
#define M 2005
using namespace std;
struct N{
    ll x,y;
}dp[25][M];
ll pw[25],l,r;
int k,a[25],i,cnt;

N dfs(int p,int st,int lead,int limit){
    if(!p) return __builtin_popcount(st)<=k&&!lead?N{1,0}:N{0,0};
    if(!lead&&!limit&&dp[p][st].y!=-1)return dp[p][st];
    N ans=N{0,0};
    int end=(limit?a[p]:9);
    for(int i=0;i<=end;i++){
       N tp=dfs(p-1,lead&&!i?0:st|(1<<i),lead&&!i,limit&&i==end);
       ans.x=(ans.x+tp.x)%P;
       ans.y=(ans.y+tp.y+1ll*i*pw[p-1]%P*tp.x%P)%P;
    }
    if(!limit)dp[p][st]=ans;
    return ans;
}

ll cal(ll x){
     cnt=0;
    while(x>0){a[++cnt]=x%10;x/=10;}
    memset(dp,-1,sizeof(dp));
    return dfs(cnt,0,1,1).y%P;
}

int main(){
    pw[0]=1;
    for(i=1;i<=20;i++)pw[i]=pw[i-1]*10%P;
    cin>>l>>r>>k;
    cout<<(cal(r)-cal(l-1)+P)%P;
}

原文地址:https://www.cnblogs.com/VIrtu0s0/p/9895573.html

时间: 2024-11-03 15:52:30

Educational Codeforces Round 53 (Rated for Div. 2) E. Segment Sum的相关文章

Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot 【二分 + 尺取】

任意门:http://codeforces.com/contest/1073/problem/C C. Vasya and Robot time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasya has got a robot which is situated on an infinite Cartesian plane, i

Educational Codeforces Round 53 (Rated for Div. 2)

A. Diverse Substring(前缀和) 题意:给一个字符串,找出一个子串满足该子串中每个字母出现的次数不超过子串的长度/2,字符串的长度n<1000. 题解:n方枚举子串的起点和终点,对于每个字母建一个前缀和就能知道在任意一个字串中每个字母出现的个数了. 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; char s[1010]; int n;

Educational Codeforces Round 53 (Rated for Div. 2)G. Yet Another LCP Problem

题意:给串s,每次询问k个数a,l个数b,问a和b作为后缀的lcp的综合 题解:和bzoj3879类似,反向sam日神仙...lcp就是fail树上的lca.把点抠出来建虚树,然后在上面dp即可.(感觉之前写的svt什么玩意) //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pragma GCC optimize("unroll-loops") //#pragma comm

Educational Codeforces Round 78 (Rated for Div. 2) D. Segment Tree

链接: https://codeforces.com/contest/1278/problem/D 题意: As the name of the task implies, you are asked to do some work with segments and trees. Recall that a tree is a connected undirected graph such that there is exactly one simple path between every

Educational Codeforces Round 48 (Rated for Div. 2) B Segment Occurrences

翻译 给你一个字符串\(s\)和另一个字符串\(t\),然后给你\(q\)个区间,问\(s\)在这些区间里的子串有多少个与\(t\)相同. 思路 一道要细心的模拟题,使用\(STL string\),暴力,前缀和,\(Hash\),\(Kmp\)都能做出来,然后我来介绍一下用 \(vector\)的做法. 首先预处理\(s\),从头到位找到每一个长度是字符串t的长度\(m\)的字符串,如果其与\(t\)相等,那么就往vector中压入\(1\),否则压入\(0\),这样,我们就找到每个编号的字符

Educational Codeforces Round 84 (Rated for Div. 2), problem: (A) Sum of Odd Integers

A. 被卡了好久,样例的第一感觉n%k==0则YES 后来写式子,交了发n>=k*k 虽然写的时候也注意到了n-k必须是偶数(k个奇数和的奇偶性与k相同,故n与k奇偶性相同) 最后才想到,可以构造 前k-1个数为1~k-1 剩下的即为第k个数 #include<bits/stdc++.h> #define ll long long using namespace std; //const int N=1e4+5; int main(){ int T; ios::sync_with_std

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars

Educational Codeforces Round 69 (Rated for Div. 2) B - Pillars There are n pillars aligned in a row and numbered from 1 to n. Initially each pillar contains exactly one disk. The i-th pillar contains a disk having radius ai. You can move these disks

Educational Codeforces Round 71 (Rated for Div. 2) D - Number Of Permutations

原文链接:https://www.cnblogs.com/xwl3109377858/p/11405773.html Educational Codeforces Round 71 (Rated for Div. 2) D - Number Of Permutations You are given a sequence of n pairs of integers: (a1,b1),(a2,b2),…,(an,bn). This sequence is called bad if it is