發表文章

目前顯示的是 12月, 2018的文章

[TIOJ] 2039. AI-666 賺多少

題目連結: https://tioj.infor.org/problems/2039 注意!以下是努力壓常數後過的$O(N \log N)$作法(雖然好像大家也都是$O(N \log C)$的aliens優化解)。 這裡講一下我的作法好了,首先我們將題目視成不斷將k變大並詢問當前最大是多少。若是只有一個k的時候,我們顯然是要找一組左低右高的區間$[a_l, a_r]$,那變成兩個的時候,我們發現其實有幾種可能,一種是在$l$左邊繼續找一組左低右高的區間,或是在$r$右邊找一組左低右高的區間,或是在$(l, r)$中找一組左高右低的區間,把他們的差加進答案即可。 所以我們可以用線段樹維護我們想知道某個區間內左高右低或左低右高的最大值,這樣我們就是每次從heap拿出一個最大的區間加進答案後,把它左右中三個區間同時再塞到heap裡,繼續做到直到沒有東東可以拿,或達到k就好。 不過一般的線段樹實作會TLE,所以我寫了個zkw再加上輸入優化後就可以AC了XD #include <bits/stdc++.h> using namespace std; using PII = pair<int,int>; #define FF first #define SS second const int N = 2000000; struct Data{ int v, p1, p2; Data():v(0),p1(-1),p2(-1){} Data(int a, int b, int c):v(a),p1(b),p2(c){} bool operator<(const Data& a) const { return v < a.v; } bool operator>(const Data& a) const { return v > a.v; } } LR[N<<2], RL[N<<2]; PII mx[N<<2], mi[N<<2]; int m; // zkw inline Data queryLR(int l, int r){ // (l, r) int b=-1,c=-1; Data ret; for(l+=m,r+=m;l^r^1