ac**
總結**
zyb最近完成了他的計算機課程。他對用於快取管理的lru演算法非常感興趣。為了簡化這個問題,假設乙個塊包含乙個名稱(這是乙個字串)和一組資料(它是乙個數字)。zyb希望用陣列實現lru演算法。他的陣列最多能容納m個元素。在開始時,陣列是空的。在每個操作中,cpu可以訪問乙個塊。zyb會用蠻力在他的陣列中搜尋它。如果這個塊存在於他的陣列中(這意味著他可以找到乙個同名的塊),他會將它從陣列中取出,並將它放回陣列的末尾。否則,他只需將其新增到陣列的末尾。如果在任何時候,陣列的大小超過了容量,他將刪除陣列中的第乙個塊(陣列前面的塊)。
看起來很無聊?有時候,zyb可能會詢問某個塊在某個塊之前或之後的資料。你能幫他寫乙個程式來實現他的目標嗎?
有很多種情況。輸入的第一行包含乙個正整數t,表示用例的數量。對於每一種情況,輸入的第一行包含兩個整數q和m(1 ≤
\leq
≤ q,m≤
\leq
≤ 500000)表示運算元和陣列容量。以下q行分別包含乙個整數opt(0 ≤
\le≤ opt ≤
\le≤ 1)、乙個字串s(1 ≤
\leq
≤ s ≤
\leq
≤ 10)和乙個整數v,由單個空格分隔,描述乙個操作。
如果opt=0,那麼|v| ≤
\le≤ 10 。操作是cpu想要訪問乙個塊。如果此訪問失敗(這意味著您無法在陣列中找到具有名稱s的塊)在陣列末尾新增乙個具有名稱s和資料v的塊,操作的結果為v。如果此訪問成功,則操作的結果是您找到的塊的資料(在本例中忽略v)。不要忘記將該塊移動到陣列的末尾。
如果opt = 1 , 那麼v的值是-1,0或1。操作是你應該回答zyb的問題。讓k是陣列中名稱s的塊的索引。然後,該操作的結果是陣列中索引為k+v的塊的資料。如果不存在這樣的塊,請輸出「invalid」(沒有引號)。
注意,zyb的問題(型別為1的操作)不算訪問,也不會導致陣列被更新。保證在所有情況下q的和不超過1000000 ,而且s只包含數字(即『0』-『9』)
對於每種情況,在語句的輸入部分中定義的一行中列印每個操作的結果。
18 30 0101010 1
0 0101011 2
1 0101010 1
0 1100000 3
0 0101011 -1
0 1111111 4
1 0101011 -1
1 0101010 0
122對於每次操作q: opt s v3243
invalid
不存在s
查詢 不存在
題意中涉及插入、查詢操作,並且節點的位置會存在較大的變更,所以很容易想到維護乙個雙向鍊錶來應對每一次操作,並用map來存每次操作的鍵:s,值:v。由於map的插入和查詢時間是log,所以整個演算法的時間複雜度是o(qlogm)。
具體實現起來比較繁瑣,指標很容易出錯,這裡貼一下我遇到過的錯誤
段錯誤可能是鍊錶在solve()中建立,記憶體不足導致的
for中呼叫q次solve也會造成很大的開銷
使用cin、cout超時,加了ios::sync_with_stdio(false)也一樣
將字串轉換為整形時int不夠十位name結果溢位導致最終答案錯誤
將字串轉換為整形時,前導0個數不同被判定為相同,如001,01
參考這裡膜拜下咖啡雞orz簡潔而優美的**
#include
#include
#include
using namespace std;
typedef
long
long ll;
class node};
node pool[
500005*2
],*cur;
//開兩倍的話可以滿足從中間插入到最後的情況
int q,m,t;
int opt,v,ans;
char s[15]
;map> mp;
node* head;
node* tail;
int num;
//鍊錶中節點個數
node *
newnode
(ll name,
int value)
void
del(node *p)
void
insert_back
(node *p)
void
init()
void
solve()
}else
}else
if(opt==1)
else}if
(ans==
-100
)else}}
intmain()
return0;
}
本題思路不難,主要是雙向鍊錶的實現和維護很容易出錯。
需要熟悉map的使用以及雙向鍊錶
牛客暑期多校訓練營B Boundary
給定n個點,然後確定乙個過原點的圓,要使這n個點盡可能多的存在與圓上,最後輸出最多的存在於圓上的點的個數 三點確定乙個圓,我們已知這個圓必定經過原點,所以再依次利用三點求圓心的公式列舉每兩個點與原點 三點不共線 確定的圓心,最後選擇確定次數最多的圓心構成的圓 include include incl...
2019牛客暑期多校訓練營(第九場)
d knapsack cryptosystem 折半搜尋,晚上又去看了挑戰程式設計,對於時間複雜度高的情況,可以通過犧牲空間來降低時間複雜度。先把前半部分所有可以組合的情況列舉出來,然後對於後半部分依次列舉,那麼複雜度變化為o 2 36 o 2 18 2 18log 18 顯然就可做了,折半的裸題。...
2019牛客暑期多校訓練營(第五場)
2019牛客暑期多校訓練營 第五場 題號標題 已通過 題解 討論 通過率團隊的狀態 adigits 2 1016 2378通過b generator 1 513 3524通過c generator 2 34 592已補d generator 3 4 23 未通過e independent set 1...