設從低到高第 len
+1le
n+1 位的數字為 x
x, 考慮 x
x 與後面 len
len 位組成逆序對的貢獻,
先考慮 x=−
1x=−
1 時的貢獻, 為 len
×10l
enle
n×10
len, 其中每個數字出現的次數都相同,
再考慮 x∈[
0,9]
x∈[0
,9], 貢獻變為 len
×10l
en×x
10=le
n×10
len−
1×xl
en×1
0len
×10x
=le
n×10
len−
1×x .
設 f[i,
j]f[
i,j]
表示 x=i
x=i 右區間為 [0,
j][0
,j] 時 i
i 與 右區間 構成的貢獻, 則 f[i
,j]=
10ji
(j+1
)f[i
,j]=
10ji
(j+1
),設 [0,i
][0,
i]位 無限制地填數 產生的總逆序對為 g[i
]g[i
], 則 g[i
]=10g
[i−1
]+∑j
=09f
[j,i
]g[i
]=10
g[i−
1]+j
=0∑9
f[j
,i] .
設當前位置為 i
i, 上界為 lim
lim, 選擇的數字為 x
x, ans
ans 是初值為 0
0 的變數,
最高位為 tpt
p, ton
g[p]
tong
[p] 表示 從最高位到 第 i+1
i+1 位 p
p 數字出現的次數,su
f[p]
suf[
p]表示從 第 p
p 位 到 0
0 位 的數字轉化為十進位制後的值,
現在按位從低到高進行處理,
#include
using
namespace std;
#define reg register
typedef
long
long ll;
const
int maxn =
500005
;const
int mod =
998244353
;int t;
int len[2]
;int g[maxn]
;int pw[maxn]
;int a[2]
[maxn]
;int tong[maxn]
;int f[11]
[maxn]
;char cmp_1[maxn]
;char cmp_2[maxn]
;void
init()
}int
solve
(int fl)
/* for(reg int x = 0; x < lim; x ++)
for(reg int j = x+1; j <= 9; j ++) res += 1ll*pw[i]*tong[j] % mod, res %= mod;
*/for(reg int j =
1; j <=
9; j ++
) res +
=(std::
min(j-
1, lim-1)
+1ll
)*tong[j]
%mod*pw[i]
%mod, res -
= res>=mod?mod:0;
for(reg int j = lim+
1; j <=
9; j ++
) res +=(
1ll*suf +1)
* tong[j]
% mod, res -
= res>=mod?mod:0;
suf =
(suf +
(1ll
*lim*pw[i]
%mod)
)% mod;
}return res;
}int
main()
return0;
}
count 數字計數 (數字dp)
給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。input 輸入檔案中僅包含一行兩個整數a b,含義如上所述。output 輸出檔案中包含一行10個整數,分別表示0 9在 a,b 中出現了多少次。sample input 1 99 sample output...
D windy數(數字dp模板)
windy定義了一種windy數。不含前導零且相鄰兩個數字之差至少為2的正整數被稱為windy數。windy想知道,在a和b之間,包括a和b,總共有多少個windy數?input 包含兩個整數,a b。output 乙個整數 sample input 輸入樣例一 1 10 輸入樣例二 25 50 s...
找順數 數字dp
輸出1到n中含有6的數的個數。100 19找規律感覺好難想 好像是什麼100以內有19個,200以內有19 2個,600以內115個,700以內214個.1000以內有271,2000以內有2 271個 就直接套數字dp的模板了。1 include2 include3 include4 using ...