2023年牛客暑期多校訓練營(第三場 )J

2021-09-25 14:29:27 字數 2690 閱讀 6760

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』)

對於每種情況,在語句的輸入部分中定義的一行中列印每個操作的結果。

1

8 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

3243

invalid

對於每次操作q: opt s v

不存在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...