1441 士兵的數字遊戲

2021-08-09 08:49:16 字數 1861 閱讀 9745

1441 士兵的數字遊戲

基準時間限制:6 秒 空間限制:131072 kb 分值: 40 難度:4級演算法題

兩個士兵正在玩乙個遊戲,遊戲開始的時候,第乙個士兵為第二個士兵選乙個正整數n。然後第二個士兵要玩盡可能多的輪數。每一輪要選擇乙個正整數x>1,且n要是x的倍數,然後用n/x去代替n。當n變成1的時候,遊戲就結束了,第二個士兵所得的分數就是他玩遊戲的輪數。為了使遊戲更加有趣,第乙個士兵用 a! / b! 來表示n。k!表示把所有1到k的數字乘起來。那麼第二個士兵所能得到的最大分數是多少呢?

input

單組測試資料。

第一行包含乙個整數t (1 ≤ t ≤ 1,000,000),表示士兵玩遊戲的次數。

接下來t行,每行包含兩個整數a,b (1 ≤ b ≤ a ≤ 5,000,000)。

output

對於每一組資料,輸出第二個士兵能拿到的最多分數。
input示例

2

3 16 3

output示例

2

5

顯然 士兵每次要選擇最小的質因子 才能使遊戲輪數最大 自己可以算一下

看到時限6s 我第一想法是 1s內跑素數篩 然後 剩下的時間處理結果

但是 20個點全tle了(t_t)

實際上 我們知道這個這個 階乘除階乘 用處不大 我們可以把它轉化一下

如果我們用質因子的冪次方來表示階乘 那麼這個式子就相當於 上面質因子的個數減去下面質因子的個數

所以我們可以用字首和sum[i]來表示 i的階乘的所有質因子的個數

我們既要篩素數 (因為求質因子個數時要用到素數表) 還要求每個數的質因子個數 (字首和無法直接求出)

我們想到了尤拉篩法 尤拉篩法可以保證 每個數隻會被他最小的素因子篩掉 也就是每個數隻會被篩一次

prime陣列中的素數是遞增的,當i能整除prime[j],那麼i*prime[j+1

]這個合數肯定被prime[j]乘以某個數篩掉。

因為i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那麼i*prime[j+1]=(k*prime[j])*prime

[j+1]=k』*prime[j],接下去的素數同理。所以不用篩下去了。因此,在滿足i%prime[j]==0這個條件之前以及第一次

滿足改條件時,prime[j]必定是prime[j]*i的最小因子。

為什麼只會被篩一次

在進行尤拉篩法的同時 我們統計每個數的素因子個數 最後在統計一次字首和 

o(1) 查詢 

預期 可以在2s內跑過 但實際上每個點最少跑了3s 連5s的都有 

可能是取模運算吧(疑惑臉)

1 #include 2 #include 3

4const

int maxn=5000010;5

6int

t,a,b,top;78

intprime[maxn],sum[maxn],t[maxn];910

bool

vis[maxn];

1112 inline void read(int&x)

1819 inline void

pre() 28}

29 sum[1]=0;sum[2]=1;30

for(int i=3;i1]+t[i];

31return;32

}3334int

hh()

41return0;

42}4344

int sb=hh();

45int main(int argc,char**argv)

**

1441 士兵的數字遊戲

1441 士兵的數字遊戲 基準時間限制 6 秒 空間限制 131072 kb 分值 兩個士兵正在玩乙個遊戲,遊戲開始的時候,第乙個士兵為第二個士兵選乙個正整數n。然後第二個士兵要玩盡可能多的輪數。每一輪要選擇乙個正整數x 1,且n要是x的倍數,然後用n x去代替n。當n變成1的時候,遊戲就結束了,第...

51nod 1441 士兵的數字遊戲 素數篩

兩個士兵正在玩乙個遊戲,遊戲開始的時候,第乙個士兵為第二個士兵選乙個正整數n。然後第二個士兵要玩盡可能多的輪數。每一輪要選擇乙個正整數x 1,且n要是x的倍數,然後用n x去代替n。當n變成1的時候,遊戲就結束了,第二個士兵所得的分數就是他玩遊戲的輪數。為了使遊戲更加有趣,第乙個士兵用 a b 來表...

51nod1441 士兵的數字遊戲 分解質因子

題目大意 兩個士兵正在玩乙個遊戲,遊戲開始的時候,第乙個士兵為第二個士兵選乙個正整數n。然後第二個士兵要玩盡可能多的輪數。每一輪要選擇乙個正整數x 1,且n要是x的倍數,然後用n x去代替n。當n變成1的時候,遊戲就結束了,第二個士兵所得的分數就是他玩遊戲的輪數。為了使遊戲更加有趣,第乙個士兵用 a...