ans:我們給棧裡的數附上第二個域,代表在這個數之前(包含這個數)的最小值。
stack> st;
void push(int new_elem));
}
另乙個表述是你有乙個長度為n的陣列,如何o(n)第從左到右詢問所有長度為m的子陣列的最小值?ans:
實現1:單調棧不能從頭部pop,如果強行增加pop函式,那麼pop掉第乙個數會需要o(n)地更新後面的數的second。
我們考慮只維護乙個單調遞減序列。
具體實現如下:
q.front()存的是佇列最小值。
push時將佇列尾部所有大於new_element的數都pop掉。
pop時先判一下要刪的數,如果已經被刪掉了就不操作。否則pop掉當前的頭。
dequeq;
void push(int new_element)
void pop(int remove_element)
但是上面的pop操作需要讀入乙個數,很不自然。
我們可以通過增加乙個儲存下標的second域來解決,
deque> q;
int cnt_added = 0;
int cnt_removed = 0;
void push(int new_element));
cnt_added++;
}void pop()
實現2:
上面的單調佇列都把除了單調遞減的數列的數刪完了,如何儲存所有元素呢?
可以直接用兩個單調棧來模擬。
往s1裡push新元素。
從s2裡pop。 如果s2空了,那麼就把s1全都放到s2裡面。
這樣就通過s2可以訪問棧的開頭元素了。
stack> s1, s2;
int query()
void push(int new_element));
}void pop());}}
int remove_element = s2.top().first;
s2.pop();
}
const int maxn=1e7;
const int k=25;
int st[maxn][k + 1];
int a[maxn];
int n;
int f(int a,int b)
void init()
int query(int l,int r)
}return ret;
}
st最強大的地方在於對於idempotence的函式(類似max,min這樣「同乙個元素被運算多次不會產生影響的函式」)可以做到o(1)查詢。
我們考慮將區間分為兩段前後有重疊部分的區間:
\(\min(\text[l][j], \text[r - 2^j + 1][j]) \quad \text j = \log_2(r - l + 1)\)
具體的實現方法就是
int log[maxn+1];
void initlog()
int query(int l,int r)
n個集合,支援o(1)合併兩個集合與查詢某元素所屬集合操作。
思想就是對每個集合建一棵樹。對每個元素維護乙個father陣列,指向其父親結點。
於是查詢就可以用o(n)地暴力找到跟結點。
合併就是將兩個根節點並到一起。
void make_set(int v)
int find_set(int v)
void union_sets(int a, int b)
路徑壓縮+壓行
//int n;int fa[maxn];
void init()
int find(int x) return fa[x] = find(fa[x]);}
void un(int x, int y)
資料結構入門
資料 data 是客觀事物的符號表示。在電腦科學中指的是所有能輸入到計算機中並被電腦程式處理的符號的總稱。資料元素 data element 是資料的基本單位,在程式中通常作為乙個整體來進行考慮和處理。乙個資料元素可由若干個資料項 data item 組成。資料項是資料的不可分割的最小單位。資料項是...
資料結構入門
需要明確的幾個問題 1.什麼是資料結構?資料結構是一門研究非數值計算的程式設計問題中的操作物件,以及它們之間的關係和操作等相關問題的學科。簡單的來說數 據結構就是關係,就是資料元素相互之間存在的一種或多種特定關係的集合。2.資料結構研究什麼?1 資料的儲存 2 資料的操作 3.學習資料結構有什麼作用...
資料結構入門
資料 是描述客觀事物的符號,是計算機中可以操作的物件,是能被計算機識別,並輸入給計算機處理的符號集合。前提 助於理解 1.可以輸入到計算機中 2.能被電腦程式處理 舉例 整型資料,聲音,影象等 資料物件 性質相同的資料元素的集合,是資料的子集 這裡解釋一下性質相同 具有相同數量和型別的資料項 比如 ...