題目背景
smart最近沉迷於對約數的研究中。
題目描述
對於乙個數x,函式f(x)表示x所有約數的和。例如:f(6)=1+2+3+6=12。對於乙個x,smart可以很快的算出f(x)。現在的問題是,給定兩個正整數x,y(x輸入格式:
輸入檔案僅一行,兩個正整數x和y(x輸出格式:
輸出只有一行,為f(x)+f(x+1)+……+f(y)的值。
思路
首先利用字首和的思想, 我們只要能求出 1−n 的約數和的和, 就能求出一段區間的約數和的和
那麼如何快速求出從 1 開始約數和的和呢
很樸素大暴力萬歲!的演算法是 o
no\sqrt
on計算每個數的約數進行累加 ,然後慢到**
我們可以換種思維, 考慮列舉約數
顯然對於乙個約數 d , 在 1−n **現過 ⌊nd
⌋\left\lfloor\frac\right\rfloor
⌊dn
⌋ 次, 所以這一約數貢獻的答案為 ⌊nd
⌋∗
d\left\lfloor\frac\right\rfloor * d
⌊dn⌋∗
d所以 1−n 總因數和為∑i=
1n⌊n
i⌋∗i
\sum_^\left\lfloor\frac\right\rfloor * i
∑i=1n
⌊in
⌋∗i
這樣依然需要列舉 1−n 這 n 個因數, o(n) 依然達不到複雜度要求
其實看到 ⌊nd
⌋\left\lfloor\frac\right\rfloor
⌊dn
⌋ 時我們很興奮: 除法分塊!
(之前學的除法分塊是假的。。現在補個真的)
比如說當 n=12 時, 我們分別計算 ⌊ni
⌋\left\lfloor\frac\right\rfloor
⌊in
⌋ (1<=i<=n) 可以得到以下結果:12,6,4,3,2,2,1,1,1,1,1,1
注意有部分連續的向下取整值是一樣的!除法分塊就是 利用打表找規律 來求出每個區間的左右端點以達到進行快速運算的目的
左端點很容易求解, 即為上乙個右端點 +1(初始值為1)
右端點通過打表找規律可知: r=n/(n/l)
意思是因子為1的有12個,貢獻為12 * 1 = 12,因子為2的有6個,貢獻為6 * 2 = 12,因子為3的有4個,貢獻為3 * 4 = 12,以此類推。
code
#include
using
namespace std;
typedef
long
long ll;
ll x, y;
ll get_sum
(ll n)
return ans;
}int
main()
DTD約束和SCHEMA約束
dtd語法 元素 屬性 格式 schema約束 乙個xml文件中可以新增多個schema約束 xml和schema的關聯.格式 根標籤 xmlns 根標籤 xmlns 別名 命名空間 關聯約束檔案 規定元素是 於那個約束檔案的 例如 乙個約束檔案中規定 table 有屬性 row和col 還有乙個約...
約束和索引
1.主鍵約束 primary key 1 主鍵用於唯一地標識表中的每一條記錄,可以定義一列或多列為主鍵。2 是不可能 或很難 更新 3 主鍵列上沒有任何兩行具有相同值 即重複值 不允許空 null 4 主健可作外健,唯一索引不可 2.唯一性約束 unique 1 唯一性約束用來限制不受主鍵約束的列上...
約束和索引
作用 是為了保證資料的完整性而實現的摘自一套機制,它具體的根據各個不同的資料庫的實現而有不同的工具 約束 作用 快速定位特定資料,提高查詢效率,確保資料的唯一性,快速定位特定資料 可以加速表和表之間的連線,實現表與表之間的參照完整性,使用分組和排序語句進行資料檢索時,可以顯著減少分組和排序的時間全文...