本週總結 雜湊表+逆元儲存原根的離散對數
如果要打表儲存某個素數的原根的所有的相關的離散對數,而這個素數又比較大,那麼可以通過雜湊表和逆元結合來儲存,g^z =g^km+r,g為原根,r=z%m; g^m * x =1%p; 那麼如果y=g^z,
yx=g^e,
yx=g^(z-m) (g^m) x%p = ( g^e)%p; 由於(g^m) x=1%p;
那麼 z=m+e;
那麼根據這個性質,就可以建立這樣一個雜湊表,假設素數大小約為10000,那麼,可以建一個100長度的雜湊表,所掛連結串列的長度也為100,那麼上面的m的值就是100,建立起1到100這一百個離散對數與g的次方的雜湊表後,在查詢y對應值的過程中,如果找不到,就乘以g^m的逆元后繼續找,若找到後,相應的離散對數值加上m,這樣的話就可以吧10000長度的表長縮短為幾百,並且查詢過程最壞也就是查詢100次,由於是對模素數的值進行雜湊,所得到的的雜湊表的衝突較小,這樣用時間換空間,就可以取得不錯的效果,當素數的大小達到1e7或1e8時,就能大大降低空間複雜度。
參考的網上的程式碼。
struct HASH_TABLE {
ll top, gm, inv, m, pri;
ll hash_table[hash_size], mp[hash_size];
ll head[hash_size], nxt[hash_size];
void init() {
top = 1;
memset(hash_table, 0, sizeof hash_table);
memset(nxt, 0, sizeof nxt);
memset(head, -1, sizeof head);
}
void init_table(ll g, ll p) {
m = maxn; ll e = 1;
for(ll i = 0; i < m; i++) {
ll id = e % hash_size;
if(~head[id]) nxt[top] = head[id];
head[id] = top;
hash_table[top] = e; mp[top] = i;
e = e * g % p; top++;
}
gm = e; pri = p;
inv = exgcd(gm, p, 1);
}
ll query(ll x) {
for(ll i = 0; i <= pri / m; i++) {
ll id = x % hash_size;
ll hd = head[id];
if(~hd) for( ; hd; hd = nxt[hd]) {
if(hash_table[hd] == x) return i * m + mp[hd];
}
x = x * inv % pri;
}
return -1;
}
} hs;
盧卡斯定理由於複雜度是o(p),卡點經常是素數太大,詢問次數太多,或者是一個數可以分解成多個大素數相乘,從而使直接盧卡斯的時間複雜度較高,這時候就要預處理以及運用擴充套件盧卡斯定理的一些知識,但不是對擴充套件盧卡斯定理的模板的直接套用。
由於原根有一條較強的性質g的1到fi(p)次方對應1到p-1,所以在涉及到有關模p情況下的(x)^y的這種形式,x就可以用g的相應次方來替換掉,從而得到進一步的結果,也方便運用尤拉函式,gcd進行一些推導。
對於數學漸漸的有一些感覺了,雖然在做一些題目的過程中經常被一些小的細節卡很長時間,細節多的話一兩天都不能完全搞定。很難從一種形式過度到另一種形式,但理解起來沒有那麼費勁了,細節上的過度點很重要,比如說 x|m*p,那麼p就是x/gcd(m,x)的倍數,這樣就從整除引入了gcd,其實就是把x和m的共同因子去掉,又由於m/gcd(m,x)與x/gcd(m,x)互素,那麼x中剩下的因子就只能由p來包含。本質上還是因數與因數之間的關係的另一種表現形式, 其實,整個整數集合的各種關係都是以素數,因數為本質的各種表現形式。
接觸了一些有關莫比烏斯的一些東西,其實也就是把之前的知識點全部融入到了一個新的體系中,銜接更緊密了,如果把莫比烏斯涉及的推導以及之前的各種知識點慢慢的都關聯到一起,那麼一些細節過度點的尋找銜接就會有所突破。
相關文章
- 實現鍵值對儲存(五):雜湊表實現
- 淺析雜湊儲存
- 資料結構與演算法——雜湊表類的C++實現(分離連結雜湊表)資料結構演算法C++
- 資料結構複習一:雜湊表的總結資料結構
- 雜湊表(雜湊表)詳解
- 雜湊表(雜湊表)原理詳解
- 【六褘-Java】雜湊演算法記憶體圖;set集合低層採用雜湊表儲存元素;雜湊演算法的流程Java演算法記憶體
- 資料結構——雜湊表資料結構
- 資料結構與演算法整理總結---雜湊表資料結構演算法
- InnoDB儲存引擎——自適應雜湊索引儲存引擎索引
- 雜湊表
- 本週總結
- 雜湊表的原理
- 資料結構之「雜湊表」資料結構
- 雜湊表知識點小結
- 資料結構 - 雜湊表,初探資料結構
- Day76.雜湊表、雜湊函式的構造 -資料結構函式資料結構
- 資料結構與演算法分析-分離連結雜湊表的實現資料結構演算法
- 【尋跡#3】 雜湊與雜湊表
- 【資料結構與演算法學習】雜湊表(Hash Table,雜湊表)資料結構演算法
- 刷題總結:使用Python-雜湊表——兩數之和、兩個陣列的交集Python陣列
- 字串雜湊表字串
- 6.7雜湊表
- 四.(3-4)儲存管理的離散分配方式
- 查詢(3)--雜湊表(雜湊查詢)
- 圖解兩數之和:雜湊表法圖解
- JAVA資料結構之雜湊表Java資料結構
- 資料結構基礎--雜湊表資料結構
- 資料結構 - 雜湊表,再探資料結構
- 資料結構與演算法——雜湊表類的C++實現(探測雜湊表)資料結構演算法C++
- 一個根據已有表結構來建立新表的儲存過程儲存過程
- 幾道和雜湊(雜湊)表有關的面試題面試題
- 深入理解雜湊表(JAVA和Redis雜湊表實現)JavaRedis
- 雜湊表應用
- 實現雜湊表
- 淺談雜湊表
- 【PHP資料結構】雜湊表查詢PHP資料結構
- 資料結構雜湊表(c語言)資料結構C語言