樣例1輸入:
6 78 6 7 4 5 9
2 4 5
4 1 4
6 2 7
1 5 2
3 4 8
4 3 1
3 1 3
樣例1輸出:79
8786
5 樣例1每次提供完新壽司後,顧客擁有的壽司**依次為:
1.8 5 6 4 5 9
2.8 5 6 4 4 5
3.7 5 6 4 4 5
4.2 5 6 4 4 5
5.2 5 6 4 4 5
6.2 5 5 1 4 4
7.2 5 3 1 4 4
樣例2輸入:
4 25 2 4 7
1 4 3
1 4 1
樣例2輸出:75
樣例3輸入:
10 10
19 5 8 17 14 3 9 10 7 6
1 8 4
7 3 2
5 9 10
4 8 3
10 3 6
8 7 4
6 6 3
2 9 12
6 3 7
9 6 3
樣例3輸出:
1910
1417810
3127n<=40w,q<=2.5w,時限4s
考慮分塊,顯然,每一次進入區間後,壽司的數量是不會變的,而且,壽司滾出這個區間之後顯然是這段區間+新壽司中的最大值,因此我們可以用大根堆來維護每乙個塊的最大值,那麼每乙個塊滾出壽司最大值之後,最後滾出的壽司必然也是最大值。
整塊搞好了,那麼如何處理散塊呢?只有散塊我們需要具體的值,所以我們可以像線段樹一樣向塊打標記,等到成為散塊處理的時候再更新。因為是按順序滾的,而且每個人都會選擇最小值,所以我們用小根堆維護。
至此,小根堆+大根堆+分塊完美解決,時間複雜度q√nlogn
……值得注意的是,直接用stl會炸,因此我們需要一些優化~詳見**
#includeusing namespace std;
const int n = 4e5+10,m = 25010,maxsiz = 637;
#define inc(i,l,r) for(register int i=(l);i<=(r);++i)
int n,q,a[n];
int siz,bl[n];
vectorvec[maxsiz];//記錄修改操作
priority_queuemax[maxsiz];//大根堆
inline void construct(int idx)
inline void init()
inline void update(int idx)
construct(idx);
vec[idx].clear();
}inline int query(int l,int r,int k)else
update(bl[r]);
inc(i,(bl[r]-1)*siz+1,r)if(a[i]>ret)swap(a[i],ret);
construct(bl[r]);
}return ret;
}inline void solv()
}int main()
美團筆試 迴轉壽司
小美請小團吃迴轉壽司。轉盤上有n盤壽司圍成一圈,第1盤與第2盤相鄰,第2盤與第3盤相鄰,第n 1盤與第n盤相鄰,第n盤與第1盤相鄰。小團認為第i盤壽司的美味值為a i 可能是負值,如果小團討厭這盤壽司 現在,小團要在轉盤上選出連續的若干盤壽司,使得這些壽司的美味值之和最大 允許不選任何壽司,此時美味...
線段樹 CDQ分治 迴轉壽司
給你乙個序列,求連續子串行和在 l,r 之間的方案數 n 100000,ai 100000,0 l,r 109.這是我打的第一題cdq 太菜了 我對這題印象很深刻 當時大家有各種做法 好像都是線段樹?然後這時出現了一股清流 dhr的cdq分治 orz dhr 好短啊 然後愉悅的改完後就沒管了 很久以...
BJOI2016 迴轉壽司
題目鏈結 給定乙個長度為 n 的序列 a 和乙個區間 l,r 求多少連續子串行的權值和在區間內,即滿足 1 le i le j le n 且滿足 l le sum a i le r 的方案數。區間和,很容易想到用字首和轉換,這樣區間相關變成了兩個點。設 s 為 a 的字首和,那麼統計就變成了這樣。統...