總是聽高屆的大佬說,乙個字串hash,能搞出大部分的字串題,hash真的有那麼神嗎?
答:是的
近來,參加很多noip模擬賽,其中一場設計判斷大整數是否存在偷懶了一下,開了乙個map原本能a的題t掉了三個點,oj上評測t3個點還跑了1480ms,忍痛改hash後發現a了只跑了356ms
對於整數的判重、hash事實上有很多方法,具體應用要看資料範圍和題目要求
看大整數hash好多部落格都是工業程式設計,那我就寫個oi的吧,接下來就列舉一些常見判重方法
陣列判重是一種較為常見的方式,我以前很常用,桶排序(多種叫法)就是類似於這樣的
優點:速度快,單次o(1),支援統計次數,可以動態
缺點:支援範圍小,陣列可能會開不下,資料在10^8及以上基本就不能使用了
set、map判重簡單又方便,還有各種高階功能,但由於呼叫stl,速度會有點慢
優點:功能多,使用方便,一般資料不大可以使用,map支援統計次數,可以動態,支援的範圍較大,只要數字數量不爆就能開下
缺點:速度較慢,常數可能會優點大,單次o(logn)
二分判重,比較傳統,手打的常數小,相較於map效能更好,但是功能不多
優點:常數小,支援範圍也較大(同set、map),較為簡單
缺點:單次還是o(logn),功能少,不支援動態,而且統計次數會增加常數
各種平衡樹都還行,但是我比較菜,手打容易打掛,但是整體效能不得不承認還是可以的
優點:常數小,支援範圍也較大(同set、map),功能也比較多,支援動態還能統計次數
缺點:單次還是o(logn),打起來麻煩
hash真的有用,信仰的力量!!!
優點:常數小,支援範圍較大,支援動態、可以統計次數,單次o(1)!!!打起來也不煩
缺點:打hash要看臉,可以故意來卡你(但隨機數一般卡不了)
具體**+注釋介紹
#include
#include
inline
int max(const
int a,const
int b)//手寫,讓這些函式的常數小一點
inline
int min(const
int a,const
int b)
inline
void swap(int&a,int&b)
inline
void read(int&x)//可讀負數的讀入優化
while('0'
<=cu&&cu<='9')x=x*10+cu-'0',cu=getchar();
if(fla)x=-x;
}void printe(const
int x)
inline
void print(const
int x)//可輸負數的輸出優化
namespace bighash//打板子,當然放乙個namespace方便使用
tmp++;
nxt[tmp]=head[whom];
head[whom]=tmp;
tow[tmp]=x;
vau[tmp]++;
}inline
bool find(const
int x)//查詢元素是否存在1存在0不存在
inline
int get(const
int x)//獲得數字x的數量
inline
void init()//初始化
}using
namespace bighash;
int main()
read(q);//詢問
for(int i=1;i<=q;i++)
return
0;}
這個hash的原理其實很簡單,如圖,具體會不會被卡要看你的模數咋樣,一般取乙個質數比較保險
嗯,就講到這吧,如發現有問題可以提出,有問題也可以問我哦
整數的Hash函式
常用的方法有三種 直接取餘法 乘積取整法 平方取中法。下面我們對這三種方法分別進行討論。以下假定我們的關鍵字是,hash表的容量是,hash函式為 1 直接取餘法 我們用關鍵字 除以 取餘數作為在hash表中的位置。函式表示式可以寫成 例如,表容量 關鍵值 那麼 該方法的好處是實現容易且速度快,是很...
整數的Hash函式
常用的方法有三種 直接取餘法 乘積取整法 平方取中法。下面我們對這三種方法分別進行討論。以下假定我們的關鍵字是,hash表的容量是,hash函式為 1 直接取餘法 我們用關鍵字 除以 取餘數作為在hash表中的位置。函式表示式可以寫成 例如,表容量 關鍵值 那麼 該方法的好處是實現容易且速度快,是很...
演算法筆記 HASH整數雜湊
雜湊 hash 這種演算法,就是為了避免遍歷整個陣列而計算輸入的整數出現的次數.這樣大大減少了複雜度.當讀入的數為x時,就令hashtable x true 說明 hashtable陣列需要初始化為false,表示初始狀態下所有數都未出現過.以下程式判斷數字x是否出現過 include includ...