題目鏈結
題目大意:乙個區間內有n個數字,有m個詢問,每次詢問乙個區間。回答這個區間的第k大的熱度值。
熱度值定義:數字i的熱度值為:這個區間內i的出現次數。
權值分塊;莫隊演算法
首先暴力做法:對於每乙個區間,暴力搜尋出每個數字的出現次數,把出現次數push到乙個陣列裡面,尋找到出現次數的第k大的數字。
優化尋找第k大數字,可以採用權值分塊的方法。
一共n個數字,因此熱度值的取值範圍是[0,
n]
[0,n]
[0,n
],所以把這個區間進行分塊,維護每個塊中熱度值分布情況以及總的熱度值個數。這樣可以在n
\sqrt
n的複雜度內求出第k大熱度值。
具體做法:(qu函式)
1.從前往後遍歷每個塊,統計當前熱度值個數。
2.如果加上當前塊之後熱度值個數大於k,就開始遍歷塊中的熱度值
具體的add、remove操作見**
注意由於資料規模為1e9,因此需要離散化
#include
using
namespace std;
intread()
while
(s>=
'0'&&s<=
'9')
return x*f;
}const
int n=
1e5+5;
int n,m;
struct queryq[n]
;int a[n]
;int block,num;
int belong[n]
;int ls[n]
,rs[n]
;void
build()
rs[num]
=n;}
int pos[n]
;//離散化
int cnt[n]
;//記錄數字i出現了幾次
int tot[n]
;//值域分塊-單點 tot[i]表示出現過i次的數字有幾個(熱度值為i的有幾個)
int sum[n]
;//值域分塊-分塊
int all;
//有幾個熱度值
void
modify
(int x,
int c)
intqu
(int k)}}
return k;
}void
add(
int x)
void
remove
(int x)
bool
operator
<
(query a,query b)
int ans[n]
;int
main()
sort
(pos+
1,pos+
1+n)
;int len=
unique
(pos+
1,pos+
1+n)-1
-pos;
for(
int i=
1;i<=n;i++
)a[i]
=lower_bound
(pos+
1,pos+
1+n,a[i]
)-pos;
//離散化
for(
int i=
1;i<=m;i++
)build()
;sort
(q+1
,q+1
+m);
int l=
1,r=0;
for(
int i=
1;i<=m;i++
)for
(int i=
1;i<=m;i++
)printf
("%d\n"
,ans[i]);
}
曼哈頓距離最小生成樹與莫隊演算法
一 曼哈頓距離最小生成樹 曼哈頓距離最小生成樹問題可以簡述如下 給定二維平面上的n個點,在兩點之間連邊的代價為其曼哈頓距離,求使所有點連通的最小代價。樸素的演算法可以用o n2 的prim,或者處理出所有邊做kruskal,但在這裡總邊數有o n2 條,所以kruskal的複雜度變成了o n2log...
莫隊演算法(最小曼哈頓生成樹或者分塊處理)
莫隊演算法是一種離線處理區間問題很強的演算法,簡單學了下。例題 這題沒有地方提交,解答在犇犇部落格裡很清楚,反正就是分塊,然後按照l所在塊號,和右端點排序,離線搞 貼個kuangbin菊苣的 當莫隊的模版把 還有就是最小曼哈頓生成樹 這個就是把平面分成8塊,然後在45度裡求解,然後翻轉3次,就能求出...
洛谷P1972(莫隊演算法)
hh 有一串由各種漂亮的貝殼組成的項鍊。hh 相信不同的貝殼會帶來好運,所以每次散步完後,他都會隨意取出一段貝殼,思考它們所表達的含義。hh 不斷地收集新的貝殼,因此,他的項鍊變得越來越長。有一天,他突然提出了乙個問題 某一段貝殼中,包含了多少種不同的貝殼?這個問題很難回答 因為項鍊實在是太長了。於...