題目描述
在如今的網路中,tcp 是一種被廣泛使用的網路協議,它在傳輸層提供了可靠的通訊服務。眾所周知,網路是存在時延的,例如使用者先後向伺服器傳送了兩個指令 op1 和 op2,並且希望伺服器先處理指令 op1,再處理指令 op2;但由於網路時延,這兩個指令可能會失序到達,而導致伺服器先執行了指令 op2,這是我們不希望看到的。tcp 協議擁有將失序到達的報文按順序重組的功能,一種方法是給每乙個報文打上乙個時間戳。而你今天要實現的功能比這個要簡單很多。我們需要你維護乙個伺服器,這個伺服器的功能是乙個簡單的棧,你會接收三種使用者的指令:
push x t — 表示將 x元素入棧,這條指令的時間戳為 t
pop t — 表示將棧頂元素彈出,這條指令的時間戳為 t
peak t — 使用者詢問現在棧頂元素的值,這條指令的時間戳為 t
當一條時間戳為 t 的指令到達時,你需要進行如下處理:
1.將所有之前執行的時間戳大於 t 的 push和 pop指令全部撤銷
2.執行當前這條指令
3.按時間戳順序重新執行在第 1 步被撤銷的指令
注意你不需要撤銷以及重新執行之前已經執行過的 peak 指令,也就是說每一條 peak指令只有在它到達的時候會被執行一次。
我們保證每一條指令的時間戳都是唯一的;若你在需要執行一條 pop 指令時發現當前棧為空,則當前你可以忽略這條指令。 輸入
第一行包含乙個整數 n,表示指令總數。接下來 n 行按指令到達伺服器的順序給出每一條指令,有三種型別
push x t
pop t
peak t
輸出對於每一條 peak指令,輸出對應的答案佔一行;若棧為空,輸出−1。樣例輸入:
7push 100 3
push 200 7
peak 4
push 50 2
pop 5
peak 6
peak 8
樣例輸出
100
50
200
對於 100%的資料,1 <= n <= 300000,0 <= x,t <= 1000000000。
·突出題目重點難點:
①任務按照時間順序執行,且輸入的順序不等於時間順序
②上面條件的基礎上,當前的peak命令只對在這之前的命令生效(不論時間先後,意思是後面輸入的任務不會產生或被造成影響)
③必須模擬每乙個出棧入棧的操作,否則無法得到每一時間點的棧頂狀態
④n<=300000(logn<=18.2),猜測演算法時間複雜度t的範圍:
(o(n)的演算法不太可能) n*logn<=t
·解決方案:
基本思路可以想到是線段樹,構造線段樹的目的是維護每乙個時刻棧的出棧進棧情況:如果線段樹的各節點表示離散化後的時間點的化,那麼裡面的值就只有三種:1,0,-1。1表示進棧乙個元素(不管這個元素具體是多少,這不是線段樹要表示的),-1表示出棧乙個元素,0表示這時刻是乙個詢問。那麼維護線段樹的區間和就可以用正負表示當前棧裡有沒有元素:
根據棧的性質,上面這幅圖還有妙用:
棧是先進後出的:如果我們從x點開始,用乙個指標i向右移動,就有如下結論:【區間和sun[i,x]第一次大於0時,peak要找的元素必定在這個區間之中】(假設這是讀入的是peak x)
·在上圖中可以看出,其實一旦sum[i,x]大於0,那麼要找的數就是i這個位置push進去的數。但有一問題:線段樹是無法將葉子節點乙個個遍歷的(而且這樣做明顯時間無法承受),所以我們只能用線段樹區間拆分的思想進行類似的從後向前的遍歷:
·最後乙個問題:a,b,c區間可能答案就在裡面,但是包含了一些-1(比如說c區間長這樣:很明顯,答案就是最後乙個1,因為前面的pop即-1都無法影響它)。這些-1會讓這個區間的sum變小從而導致錯誤。所以我們作為判斷和大於零的依據不是區間和而是最大字尾和。
(注:其實字尾和做是一種改進方法,它的原版是直接在所有區間內二分找到最靠右邊的sum大於0的時間點,但這樣時間會**)
#include#include#define go(i,a,b) for(int i=a;i<=b;i++)using狂歡的隊伍已經遠去,我只能看到自己的影子……————汪峰《塵土》namespace std;const
int n=300004;
struct tcpg[n];
int n,table[n],t,root,sz,list[n],k,ll[n],rr[n],ans;
int lch[n*4],rch[n*4],sum[n*4],suffix[n*4],num[n];
void build(int& u,int l,int r)
void update(int u,int l,int r,int p,int val)
int mid=l+r>>1;
p<=mid?update(lch[u],l,mid,p,val):update(rch[u],mid+1,r,p,val);
sum[u]=sum[lch[u]]+sum[rch[u]];
suffix[u]=max(suffix[lch[u]]+sum[rch[u]],suffix[rch[u]]);
}void divide(int u,int l,int r,int l,int r)
int mid=l+r>>1;if(r<=mid)divide(lch[u],l,mid,l,r);
else
if(mid1,r,l,r);
else divide(rch[u],mid+1,r,mid+1,r),
divide(lch[u],l,mid,l,mid);
}void dichotomy(int u,int l,int r,int tmp)
ans=num[l];
}int main()
,table[++t]=y;sort(table+1,table+t+1);
go(i,
1,n)g[i].tim=lower_bound(table+1,table+t+1,g[i].tim)-table;
build(root,
1,t);
go(i,
1,n)
else suffix_tot+=sum[list[j]];
if(!get_ans)printf("
-1\n
");}}
return
0;}//
paul_guderian
網路 TCP協議!!
源埠位址和目的位址 表示資料從哪個程序來,哪個程序去 32位序號 每個tcp資料報傳送出去,需要序號進行編號,方便接受端正確的識別包的序號 32位確認序號 每個包傳送出去需要對端確認,確認序號為了給對端傳送確認序號 4位tcp報頭長度 用來表示tcp首部有多少個32bit位 4位元組 tcp最大長度...
TCP網路協議
tcp全稱為 傳輸控制協議 tcp是面向連線,保證可靠性,面向位元組流的一種網路傳輸協議。tcp協議段格式 1.源 目的 埠號 表示資料是從哪個程序來,到哪個程序去。2.32位序號與確認序號 tcp會話的每一端都包含乙個32位 bit 的序列號,該序列號被用來跟蹤該端傳送的資料量。每乙個包中都包含序...
網路協議之TCP
為了實現計算機的通訊,我們為計算機定義了一系列的通訊規則,這些規則就是協議.資料格式封裝 傳輸 將複雜的流程分解為幾個功能相對單一的子程序。osi是乙個理想的模型,因此一般網路系統只涉及其中的幾層,很少有系統能夠具有所有的7層,並完全遵循它的規定。在7層模型中,每一層都提供乙個特殊的網路功能。從網路...