Skip to content

Commit d23e974

Browse files
author
fighter
authored
CF 1073E solution
1 parent 1faa2f1 commit d23e974

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

CF/1073E.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# 题目链接
2+
3+
[E. Segment Sum](http://codeforces.com/contest/1073/problem/E)
4+
5+
# 分析
6+
7+
可以说很经典了,数位 dp,关于数位dp我也才学
8+
9+
[数位dp](https://codeforces.com/blog/entry/53960)
10+
11+
这个题目与 仅统计个数有点不同的地方在于,它要求值的和,而对于整数来说每个位是可以独立相加的,可是如果仅仅用一个状态 dp[st][pos][0/1] 表示吃状态下的最终结果的话,可能不行,因为比如
12+
13+
1232**
14+
1233** 这两种情况其实是在一个 dp 状态下的 st = 111,pos = 3
15+
所以会遗漏一些位的计算,所以我们采用 计算每个位贡献和(单独的位可相加)的方式将后面的值加起来
16+
17+
所以计算两个量一个是个数,一个是当前值
18+
19+
# code
20+
21+
```cpp
22+
#include<bits/stdc++.h>
23+
using namespace std;
24+
25+
#define MAX_VAL 110
26+
#define MAX_ARRAY_SIZE 20
27+
#define ms(x,v) memset((x),(v),sizeof(x))
28+
#define pb push_back
29+
#define fi first
30+
#define se second
31+
#define mp make_pair
32+
#define INF 0x3f3f3f3f
33+
#define MOD 998244353
34+
#define CTZ(x) __builtin_ctz(x) //the number of zeros at the end of number
35+
#define CLZ(x) __builtin_clz(x) //the number of zeros at the begin of number
36+
#define POPCNT(x) __builtin_popcount(x) //the number of ones in the number
37+
#define PARITY(x) __builtin_parity(x) //the parity(odd or even) of the number
38+
39+
typedef long long LL;
40+
typedef pair<LL,LL> Pair;
41+
int k;
42+
LL a,b;
43+
int num[MAX_ARRAY_SIZE],cnt;
44+
LL dp[1<<10][MAX_ARRAY_SIZE][2];
45+
LL ans[1<<10][MAX_ARRAY_SIZE][2];
46+
LL pw[MAX_ARRAY_SIZE];
47+
48+
pair<LL,LL> calc(const int st,const int pos,const int f){
49+
if(POPCNT(st)>k)return mp(0,0);
50+
if(pos == cnt){
51+
return mp(0,1);
52+
}
53+
pair<LL,LL> ret = mp(ans[st][pos][f],dp[st][pos][f]);
54+
if(ret.se !=-1)return ret;
55+
ret = mp(0,0);
56+
int lmt = f? 9: num[pos];
57+
for(int i=0 ; i<=lmt ; ++i){
58+
Pair tmp=mp(0,0);
59+
if(st ==0){
60+
tmp = calc(i?1<<i : 0,pos+1,f||i<lmt);
61+
}
62+
else{
63+
tmp = calc(st|1<<i,pos+1,f||i<lmt);
64+
}
65+
ret.fi += i*pw[cnt-pos-1]%MOD * tmp.se % MOD+ tmp.fi;
66+
ret.se += tmp.se;
67+
}
68+
return mp(ans[st][pos][f] = ret.fi % MOD, dp[st][pos][f] = ret.se %MOD);
69+
}
70+
71+
LL solve(const LL n){
72+
cnt =0;
73+
ms(dp,-1);
74+
ms(ans,-1);
75+
LL debug_n = n;
76+
while (debug_n) {
77+
num[cnt++] = debug_n % 10;
78+
debug_n/=10;
79+
}
80+
reverse(num,num+cnt);
81+
Pair ret = calc(0,0,0);
82+
return ret.fi;
83+
}
84+
85+
86+
int main (int argc, char const *argv[]) {
87+
ios_base::sync_with_stdio(0);
88+
cin.tie(0);
89+
pw[0] =1;
90+
for(int i=1 ; i<MAX_ARRAY_SIZE ; ++i)pw[i] = pw[i-1]*10 %MOD;
91+
92+
cin >> a >> b >> k;
93+
std::cout << (solve(b) - solve(a -1) + MOD) % MOD << '\n';
94+
return 0;
95+
}
96+
97+
```

0 commit comments

Comments
 (0)