發表文章

目前顯示的是有「單調隊列」標籤的文章

[TIOJ] 1637. 我愛台灣

題目連結: http://tioj.infor.org/problems/1637 枚舉每個點,看有哪些區間會以他為最大值,若是裸著做可能會有個$O(n^2)$的作法,但是其實會發現維護那些區間會以他為最大值,其實可以先找出最長且以他為最大值的區間,而要做這件事就只要用個stack維護一下左邊右邊第一個比自己大的數在哪就好(維護stack的遞減性就可做到)。維護好後算答案其實也不難,區間的可能個數就是右邊元素的數量乘以左邊元素的數量。 #include <bits/stdc++.h> using namespace std; typedef long long lld; typedef pair<lld, int> PLI; #define FF first #define SS second const int N = 1000000 + 5; lld arr[N], LL[N], RR[N]; vector<PLI> ss; int main(){ ios_base::sync_with_stdio(0);cin.tie(0); int n; cin>>n; for(int i=0;i<n-1;i++) cin>>arr[i]; for(int i=0;i<n-1;i++){ while(!ss.empty() and ss.back() < (PLI){arr[i], i}) ss.pop_back(); LL[i] = ss.empty()?-1:ss.back().SS; ss.push_back({arr[i], i}); } ss.clear(); for(int i=n-2;i>=0;i--){ while(!ss.empty() and ss.back() < (PLI){arr[i], i}) ss.pop_back(); RR[i] =...

[Codeforces] 198E. Gripping Story

題目連結: http://codeforces.com/contest/198/problem/E 被雷了才會QQ 會發現其實他是個圓並不重要,重要的其實是距離,所以不妨把每個人的座標轉換成跟原點的距離,這樣的話每次詢問就變成詢問一個距離內質量小於k的數有誰,而我們其實也不用一次把一坨東西拉出來,只要一次拉一個就好,反正最多拉n個,複雜度不會太慘。而這樣其實就是詢問一個前綴極值就可達到這件事,所以就開個BIT套個單調的queue之類的就可以做到這件事了。 #include <bits/stdc++.h> using namespace std; typedef long long lld; #define PB push_back #define ALL(x) begin(x), end(x) #define FF first #define SS second const int N = 250000 + 5; const lld INF = 1LL<<31; class LiSan{ private: vector<lld> vv; public: inline void init(){vv.clear();} inline void insert(lld x){vv.PB(x);} inline void done(){ sort(ALL(vv)); vv.resize(distance(vv.begin(), unique(ALL(vv)))); } inline int size(){return vv.size();} inline int get(lld x){ return distance(vv.begin(), lower_bound(ALL(vv), x)); } inline lld ...

[TIOJ] 1566. 簡單易懂的現代都市

題目連結: http://tioj.infor.org/problems/ 單調隊列的應用,維護兩條單調隊列,一個存最大值,一個存最小值。然後判一下最大減最小是否恰等於k即可。(單調隊列維護方法就是讓隊列呈現遞(增|減),在加入元素的時候把比較(小|大)的全部移掉,同時把最(大|小)值移掉,直到他合法。) #include <bits/stdc++.h> using namespace std; typedef long long lld; #define PB push_back typedef pair<lld,int> PLI; typedef pair<int,int> PII; #define FF first #define SS second const int N = 10000000 + 5; int main(){ ios_base::sync_with_stdio(0);cin.tie(0); int n, m;lld k; while(cin>>n>>m>>k){ deque<PLI> mi, mx; vector<PII> ans; for(int i=1;i<=n;i++){ lld x; cin>>x; while(!mi.empty() and i-mi.front().SS >= m) mi.pop_front(); while(!mx.empty() and i-mx.front().SS >= m) mx.pop_front(); while(!mi.empty() and mi.back().FF > x) mi.pop_back(); while(!mx.empty() and mx.back().FF < x) mx.pop_b...