BZOJ 3679 數字之積

2021-07-04 05:27:08 字數 1341 閱讀 2691

人生第一道數字dp,首先對於每位數的乘積,有乙個很顯然的轉移方程 d[

i][j

] 表示

i 位數乘積為

j的方案數,則有 d[

i][j

]=∑1

≤k≤9

,k|j

d[i−

1][k

/j]

然而我們發現j可能很大,但經過實驗發現只有5000餘個,於是我們可以吧第二維下標換成在數表中的排名,單個遞推就可做了;

對於區間[1

,x) 統計答案,是數字dp慣用的思路,先統計出位數比

x 小的答案數,再將

x逐位拆分,每次統計當前位嚴格小於當前位上

x 原數字的答案,處理完後再將

n除去當前位上原數字,注意如果

x 出現了0,則break掉,因為題目要求大於1;以上工作要求我們把

d陣列每一層做字首和(注意做到n,否則有奇怪的問題);

統計[l,r)容斥一下就好了

code:

#include

#include

#include

#include

using

namespace

std;

long

long f[10001];

long

long d[19][10001],s[19][10001];

long

long l,r,n;

int tot=0;

long

long power(long

long a,int t)

long

long work(long

long x,int n)

for (i=1;i<=ws-1;++i)

ans=ans+s[i][upper_bound(f+1,f+tot+1,n)-f-1];

while (ws)

if (now) n/=now; else

break;

x%=power(10,ws-1); ws--;

}return ans;

}int main()

sort(f+1,f+tot+1);

s[1][0]=0;

for (i=1;i<=9;++i) d[1][i]=1;

for (j=1;j<=tot;++j)

s[1][j]=s[1][j-1]+d[1][j];

for (i=2;i<=18;++i)

ans=work(r,n)-work(l,n);

printf("%lld\n",ans);

}

BZOJ3679 數字之積

3679 數字之積 time limit 10 sec memory limit 128 mb submit 415 solved 195 submit status discuss description 乙個數x各個數字上的數之積記為f x 不含前導零 求 l,r 中滿足0 f x n的數的個數...

bzoj 3679 數字之積

乙個數x各個數字上的數之積記為f x 不含前導零 求 l,r 中滿足0 f x n的數的個數 我的做法應該在這道題裡面是最差的了,並且 應該是最醜的了 這道題的新奇的地方實際是n的範圍,不然其實上是一道大水題了。但其實也只需要改動一點小地方,因為我們發現數字之積是2,3,5,7的倍數,不會有其他的質...

bzoj 3679 數字之積

乙個數x各個數字上的數之積記為 f x 不含前導零 求 l,r 中滿足 0的數的個數 最後 f x 可以拆分成2,3,5,7的乘積,我們就將 2,3,5,7 壓進狀態,然後就是基礎的數字dp,分是否嚴格小於兩種狀態轉移即可 具體實現需要一些技巧 預處理出每乙個數含有 2,3,5,7 的個數 預處理出...