單調棧 桶 分治 奇襲

2022-03-27 09:32:45 字數 2413 閱讀 6144

問題 c: 奇襲

時間限制: 1 sec 記憶體限制: 256 mb

題目描述

由於各種原因,桐人現在被困在under world(以下簡稱uw)中,而uw馬上 要迎來最終的壓力測試——魔界入侵。

唯一乙個神一般存在的administrator被消滅了,靠原本的整合騎士的力量 是遠遠不夠的。所以愛麗絲動員了uw全體人民,與整合騎士一起抗擊魔族。

在uw的駐地可以隱約看見魔族軍隊的大本營。整合騎士們打算在魔族入侵前 發動一次奇襲,襲擊魔族大本營!

為了降低風險,愛麗絲找到了你,一名優秀斥候,希望你能在奇襲前對魔族 大本營進行偵查,並計算出襲擊的難度。

經過偵查,你繪製出了魔族大本營的地圖,然後發現,魔族大本營是乙個n ×n的網格圖,一共有n支軍隊駐紮在一些網格中(不會有兩隻軍隊駐紮在一起)。

在大本營中,每有乙個k×k(1≤k≤n)的子網格圖包含恰好k支軍隊,我們襲 擊的難度就會增加1點。

現在請你根據繪製出的地圖,告訴愛麗絲這次的襲擊行動難度有多大。

輸入 第一行,乙個正整數n,表示網格圖的大小以及軍隊數量。

接下來n行,每行兩個整數,xi,yi,表示第i支軍隊的座標。

保證每一行和每一列都恰有乙隻軍隊,即每乙個xi和每乙個yi都是不一樣 的。

輸出 一行,乙個整數表示襲擊的難度。

樣例輸入

5 1 1

3 2

2 4

5 5

4 3

樣例輸出

10 提示

【樣例解釋】

顯然,分別以(2,2)和(4,4)為左上,右下頂點的乙個子網格圖中有3支軍隊,

這為我們的難度貢獻了1點。

類似的子網格圖在原圖中能找出10個。

【資料範圍】

對於30%的資料,n ≤ 100

對於60%的資料,n ≤ 5000

對於100%的資料,n ≤ 50000

n^2效率很好想的,但如何搞出n*logn的效率。

因為方格每行每列都只有乙個,所以把它搞成乙個序列,求有多少個區間的max-min的值等於區間長度就行了。

如果列舉每個區間(說白了就是n^2)過不去的,但如果少列舉區間,而將其所包含區間不重複地篩選,那麼可以用分治。

對於乙個區間[l,r],[l,mid],[mid+1,r]繼續分治,然後處理跨過mid的區間。而對於跨過mid的區間有兩大種情況。

1,max,min均在區間的左側(均在右側與之對稱,處理方法相同)

2,min在左側,max在右側(同理)

考慮如何處理。

首先預處理出單調棧,從mid分別向左向右,處理出到此處的最大最小值。

情況1,列舉左端點,此處的max-min即為當前區間的長度(設定max,min在同一側)就可以計算出右端點的位置,判斷右端點是否在mid右側(防止加重)並判斷此點的max,min是否合適。

情況2,在這裡就用到桶了。因為當前區間滿足rmax[right])-lmin[lift]=right-lift;

移項得rmax[right]-right=lmin[lift]-lift;只要找兩邊滿足這個等式的點就行了。用桶掃完左邊,右邊去找,找到右側第乙個min<=min[l]的位置(因為是單調的,所以<=最小的不可能合適),同理第乙個max>max[l]的位置才合適。再找這兩個端點的過程中把不合適的踢出桶,合適的重新加進來。因為滿足單調,所以桶中滿足的區間也是單調的,線性找就行了。

o(n*logn^2)為什麼多了個log呢,關於對稱的情況,我單純的把區間反轉,調了個stl,省**,費時間。

#include

#include

#include

#include

#include

using

namespace

std;

int n,a[500005],tong[600010];

int lmin[500005],rmin[500005],lmax[500005],rmax[500005];

int *hh=tong+300005;//為防止越界,用了乙個指標

int get(int l,int r,int m)

for(int i=m+2;i<=r;i++)

for(int i=l;i<=m;i++)

int p=m+1,q=m+1;hh[rmax[q]-q]++;

while(q1]>lmin[l])q++,hh[rmax[q]-q]++;

while(p<=r&&rmax[p]for(int i=l;i<=m;i++)

for(int i=m+1;i<=r;i++)hh[rmax[i]-i]=0;

return s;

}inline

int work(int l,int r)

int main()

NOIP模擬 奇襲 線段樹 單調棧

題意 給定數列,求有多少個區間滿足區間最大 1 區間最小 區間長度 滿足條件為 m ax 1 m in r 1 l ma x mi n r lmax 1 min r 1 l max min r l max 1 min r 1 l ma x mi n r lma x mi n l rmax min l...

單調棧 模板 單調棧模板

biu 單調棧主要用於求取左邊第乙個比它大,或者比它小的數。就比如站隊隨便排成一列,可以求到每個人後面第乙個比他高的人。同理可以推廣至右邊,比它矮均可。這就是單調遞增棧 遞減棧,從前至 棧,從後向前入棧的區別了。單調棧比較抽象,非常具有智慧型的想法,可應用的場景相當少,根據幾個經典題目體會它的用法會...

單調佇列 單調棧

參考文章 單調佇列 poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106 m n n 106,m n n 106 m n 直接暴力求解複雜度在0 mn 可以考慮維護區間最值,單調佇列則是維護區間佇列的強大 單調佇列的定義 單調佇列實現的大致過程 1...