小明維護著乙個程式設計師論壇。現在他收集了乙份"點讚"日誌,日誌共有 n
n 行。其中每一行的格式是:
ts\ id
表示在 ts ts
時刻編號 idid
的帖子收到乙個"贊"。
現在小明想統計有哪些帖子曾經是"熱帖"。如果乙個帖子曾在任意乙個長度為 d
d 的時間段內收到不少於 k
k 個讚,小明就認為這個帖子曾是"熱帖"。
具體來說,如果存在某個時刻 t 滿足該帖在 [t,t+d)[t
,t+d
) 這段時間內(注意是左閉右開區間)收到不少於 k
k 個讚,該帖就曾是"熱帖"。
給定日誌,請你幫助小明統計出所有曾是"熱帖"的帖子編號。
輸入格式:
第一行包含三個整數 n,d,kn,
d,k。
以下 n 行每行一條日誌,包含兩個整數 ts 和 id。
其中,1 \leq k \leq n \leq 10^5, 0 \leq ts \leq 10^5,0 \leq id \leq 10^51≤
k≤n≤
105,0
≤ts≤
105,0
≤id≤
105。按從小到大的順序輸出熱帖 idid
。每個 idid
一行。示例
輸入
7 10 2
0 10 10
10 10
10 1
9 1100 3
100 3
輸出
1
3
我的**:(暴力稍微簡化,四個指標,易超時,ac不了)
#include #includeusing namespace std;
const int n = 1e5 + 10;
struct tsid
q[n];
int flag[n];
bool cmp1(tsid a, tsid b) //對id公升序
bool cmp2(tsid a, tsid b) //對時間公升序
int main()
sort(q, q + n, cmp1); //按照id排序
for (int i = 0; i < n; )
sort(q + i, q + j + 1, cmp2);
for (int x = i; x <= j - 1; )
if (y - x >= k)
else
}i = j + 1;
if (q[i].id == 0)break;
}for (int i = 1; i <= n; i++)
return 0;
}
#include #includeusing namespace std;
const int n = 1e5 + 10;
struct tsid
q[n];
int sum[n];
int flag[n];
bool cmp(tsid a, tsid b) //對時間公升序
int main()
sort(q, q + n, cmp); //對事件公升序
for (int i = 0 ,j = 0; i < n; i++)
if (sum[q[i].id] >= k)// 當前的有效贊
}for (int i = 0; i <= 1e5; i++)
return 0;
}
精妙之處:只用兩個指標,i負責記錄每乙個id的點讚數,模擬器 —— j負責隨著時間流逝 過期的把贊取消 。 雙指標演算法
雙指標演算法模板 for int i 0,j 0 i n i 常見問題分類 1 對於乙個序列,用兩個指標維護一段區間 2 對於兩個序列,維護某種次序,比如歸併排序中合併兩個有序序列的操作 例題1 最長連續不重複子序列 給定乙個長度為n的整數序列,請找出最長的不包含重複數字的連續區間,輸出它的長度。輸...
雙指標演算法
title 雙指標演算法 date 2019 05 26 23 45 09 tags 雙指標演算法 雙指標演算法 主要是兩大類 核心思想 將乙個 o n 2 o n 2 o n2 的演算法 優化成 o n o n o n 的for int i 0 i for int j 0 j for i 0,j ...
雙指標演算法
一般雙指標的模板 雙指標演算法的思考方式 先想出暴力做法,再觀察是否存在單調性。傳統的演算法需列舉兩個指標的組合,兩個for迴圈時間複雜度為o n 2 雙指標演算法會使時間複雜度變為o n 給定乙個長度為n的整數序列,請找出最長的不包含重複數字的連續區間,輸出它的長度。輸入格式 第一行包含整數n。第...