time limit: 5 sec
memory limit: 256 mb
submit: 159
solved: 17 [
submit][
status][
web board]
wanghang最近研製出了乙個機械人,這個機械人有乙個跨時代的功能:記憶數字!
這個機械人接受三種指令
第一種指令,記憶一系列數字
第二種指令,詢問乙個數字是否在機械人的記憶中
第三種指令,讓這個機械人忘記所有數字
第一行乙個正整數t<=10代表輸入資料個數
第二行乙個正整數n<=100000代表指令個數
然後n行,每行代表乙個指令,指令格式如下:
1 x k代表記憶k個數字x,x+2,x+4 ... x+2k-2 (1<=k<=50)
2 y 代表詢問y是否在機械人的記憶中
3 代表讓機械人忘記所有數字
對於每個第二種指令,輸出yes代表詢問的數字在機械人的記憶中,反之輸出no
151 1 52 22 332 2
noyesno
srssyd
考慮用hash表,插入和查詢接近o(1),clear操作是o(n)。十萬次查詢,每次查詢最多同時有五十萬個節點需要清空,時間開銷太大。如何解決clear的效率問題?
解決辦法是lazy標記,僅當使用到時才清零。具體實現是用乙個時間戳,再記錄每個鍊錶的版本號,一比較就知道是否需要更新。
感覺挺像可持久化程式設計的,其實不是。目的並不是要保留歷史版本。而是通過標記需要清空的元素,不到使用的時候就不對他進行清空,於是我們的清零的時間全部分散到了插入和查詢中。而對時間戳的更新只是o(1)的演算法。插入和查詢和原來的時間複雜度保持不變。因此這種lazy標記的思路就是乙個極好的優化。
注意,我們需要清零的是head陣列,因此每乙個煉表裡所有的元素都具有相同的時間戳,所以不應該對每個元素維護乙個時間戳,這樣對時間的優化是較小的
求hash值的時候,不要用abs。而對之and上0x7fffffff,直接捨掉符號位。這樣會使hash值分散得多,因為正負值的hash差異很大。
提交時一直re,原因是多組資料沒有的hash表clear。導致記憶體池的指標一直往後移,超過了預期的最大值maxn*maxk。
#include #include #include #include #include #include const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int maxnk = 5000005;
int getint()
do res = (res << 1) + (res << 3) + tmp - '0';
while (isdigit(tmp = getchar()));
return sgn ? res : -res;
}struct node
node(){}
};const int mod = 13131313;
struct hashtable
bool find(int v)
for (int i=head[_hash];i;i=pool[i].next)
return false;
} void insert(int v)
for (int i=head[_hash];i;i=pool[i].next)
}if (!ok)
}void clear() };
hashtable table;
int main()
{ int t = getint();
while (t--)
{ table.clear();
int n = getint();
while (n--)
{ int o = getint();
if (o == 1)
{int x = getint();
int k = getint();
for (int i=0;i
線段樹(含懶標記)模板
理解分析 鏈結 include using namespace std typedef long long ll int n,m,a,b,x,y,p,ans struct nodetree 400005 void build int k,int ll,int rr int mid ll rr 2 b...
Hash 統計數字
給定n個數,每個數均不超過1.5 109,統計這些數各自出現的次數,並按照從小到大的順序輸出統計結果。資料規模有1.5 109,所以雜湊關鍵字本身作為位址會爆 所以想到用雜湊表 除了記錄某個s是否出現,還要記錄出現的次數,所以可以用乙個二維陣列,加乙個儲存出現次數的即可。完後,將雜湊表裡的數放在乙個...
codeforces (數字dp 記憶化搜尋)
題意 列舉 a,b 之間的beautiful數 即這個數所有位上的數都能整除這個數 思路 用pos記錄位置 num記錄當前位置前面所有位組成的數 當時開不了這麼大的陣列 有知道1 9 的最小公倍數是2520 所以num記錄 上文的num 2520 就可以了 現在就剩下記錄當前位置前面各位都出現過0 ...