空間問題的簡化(單調佇列的圓環化直問題)

2021-09-20 21:55:17 字數 1239 閱讀 8916

在我們接觸的空間問題中,一般由一維直線到一維曲線(圓環)再到二維平面,最後是三維甚至是多維空間,對於多維空間來講,我們一般都是將其轉化成較低維空間,我們可以對其進行壓縮與轉化,從而簡化問題。

在二分法這裡,會有一些圓環類問題,我們可以將其進行轉化,將其變為直線型問題,這樣做更有利於我們解題。

我們通過下面這個例子來簡單看一下這個問題:

(我們可以在圓環資料進行迴圈時,將原來的nn換成2n進行簡化)

題意:由n(10^6)個資料組成的圓環,資料為1和-1,問從乙個點開始順時針或逆時針,能遍歷完所有點,並且保證中間過程中sum>=0。

分析:假設從i點開始,這裡僅考慮向左,必須保sum(j,i)>=0, i-n =0,即sum[i] - max(sum[j])>=0.

要求區間[i-n,i-1]最大值,維護單調遞減佇列即可。

#include #include #include using namespace std;

const int n = 2100000;

int n;

char a[n/2];

int num[n];

int sum[n];

int que[n/2];

bool f[n/2],f2[n/2];

void solve(bool t)

for(i = n; i <= 2*n; i++)

}}int main()

for(i = 1; i <= n; i++)

num[i+n] = num[i];

for(i = 1; i <= n*2; i++)

sum[i] = sum[i-1] + num[i];

int result = 0;

solve(true);

//reverse

for(i = 1; i <= n; i++)

sum[i] = sum[i-1] + num[n+1-i];

for(i = n+1; i <=2*n; i++)

sum[i] = sum[i-1] + num[2*n+1-i];

solve(false);

result = 0;

for(i = 0; i < n; i++)

if(f[i]||f2[n-i])

result++;

printf("case %d: %d\n",++cases,result);

}return 0;

}

單調棧,單調佇列的入門

我自己的話單調棧是也用陣列模擬出來的,我是根據這個部落格學的,原理挺簡單的,但是做題思想的轉變有點麻煩,最後陣列模擬的單調佇列其實是雙向佇列。下邊是大佬的部落格 單調佇列是什麼呢?可以直接從問題開始來展開。poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 ...

單調佇列優化的揹包問題

對於揹包問題,經典的揹包九講已經講的很明白了,本來就不打算寫這方面問題了。但是吧。我發現,那個最出名的九講竟然沒寫佇列優化的揹包。那我必須寫一下咯嘿嘿,這麼好的思想。我們回顧一下揹包問題吧。題目 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物...

1239 Easy的佇列 (單調佇列)

題目描述 easy的學生的 資料結構 考試掛掉了,他求著easy再給他一次機會,easy出了這麼一道題,如果他的學生做出來就給這個學生一次重新考試的機會,題目是這樣的 維護乙個名為佇列的資料結構,支援以下四種操作 enqueue x 將值為x的元素放入佇列的尾部 dequeue 輸出當前佇列首部的元...