洛谷 P3935 Calculating 題解

博客園同步

原題鏈接

一看我感覺是個什麼很難的式子……

結果讀完了才發現本質太簡單。

算法一

完全按照那個題目所說的,真的把質因數分解的結果保留。

最後乘。

時間複雜度:O(rr)O(r \sqrt{r}).

實際得分:40pts40pts.

(實在想不到比這得分更低的算法了)

算法二

機智的發現是個因數枚舉。

然後枚舉因數。

時間複雜度: O(rr)O(r \sqrt{r}).

實際得分: 40pts40pts.

(只是碼量少一點)

算法三

推式子。

fxf_x 其實就是 xx 的因數個數。

我們只需分別求出 i=1rfi\sum_{i=1}^r f_ii=1l1fi\sum_{i=1}^{l-1} f_i ,再相減即可。

(日常前綴和思路)

i=1rfi\sum_{i=1}^r f_i

=i=1rji1 = \sum_{i=1}^r \sum_{j|i} 1

=i=1rj=1i[ji] = \sum_{i=1}^r \sum_{j=1}^i [j|i]

=j=1ri=1r[ji] = \sum_{j=1}^r \sum_{i=1}^r [j|i]

(這步的依據是:我們不枚舉每個數的因數,而是考慮每個數作爲其它因數所產生的貢獻)

=j=1rrj = \sum_{j=1}^r \lfloor \frac{r}{j} \rfloor

(這步的依據是:從 11nn 共有 rj\lfloor \frac{r}{j} \rfloor 個數是 jj 的倍數)

然後到這裏,我們暴力枚舉。

時間複雜度: O(r)O(r).

實際得分:60pts60pts.

算法四

暴力枚舉個頭?

答案擺在面前還在那暴力

明明是整除分塊好吧。

不知道整除分塊是啥?

淺談整除分塊

OK\texttt{OK},你發現,這題竟然是 整除分塊的模板題

時間複雜度: O(r)O(\sqrt{r}).

實際得分:100pts100pts.

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MOD=998244353;

inline ll read(){char ch=getchar();ll f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	ll x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

int main(){
	ll l=read(),r=read();
	ll ans=0; l--;
	for(ll i=1,t;i<=r;i=t+1) {
		t=r/(r/i); ll len=(t-i+1)%MOD;
		ans=(ans+len*(r/i)%MOD)%MOD;
	} //這是 1~r 的
	for(ll i=1,t;i<=l;i=t+1) {
		t=l/(l/i); ll len=(t-i+1)%MOD;
		ans=(ans-len*(l/i)%MOD+MOD)%MOD; //這是 1~(l-1) 的
                //爲了防止模出負數,我們加上 MOD 再模
	} printf("%lld\n",(ans+MOD)%MOD);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章