迴轉壽司 有趣的分塊

2021-08-21 09:56:48 字數 1734 閱讀 7620

樣例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 的字首和,那麼統計就變成了這樣。統...