BZOJ 3956 Count 單調棧 ST表

2021-08-08 23:02:51 字數 865 閱讀 4368

題目傳送門

挺有思想的一題,但如果弄清楚了思路這題還是挺簡單的。

首先我們可以發揮一下自己的腦洞,發現所有的好集對不可能相交。

那麼我們可以刷兩遍單調棧,求出每個點作為區間左端點或右端點的次數。

對於給定區間,我們先找出區間中最大值所在的位置,顯然所有的好集對最多以這個位置為左端點或右端點,不可能包含這個位置。

然後問題就轉化成了求乙個區間的最大值所在的位置,計算以該位置左側所有位置為左端點的區間個數加上一該位置右側所有位置為右端點的區間個數。

(說的好繞啊,望各位大佬用心看看吧)

上面那個東西顯然可以用字首和優化一下,然後這題就a啦。

附上ac**:

#include #include #include #include using namespace std;

const int n=3e5+10;

int n,m,o,a[n],sk[n],top,mx[n][20],k,x,y;

long long l[n],r[n],ans;

inline char nc(void)

inline void read(int &a)

inline int get(int x,int y)

int main(void){

read(n),read(m),read(o);

for (int i=1; i<=n; ++i) read(a[i]),mx[i][0]=i;

sk[top=1]=a[1];

for (int i=2; i<=n; ++i){

while (top&&sk[top]y) swap(x,y);

int p=log2(y-x+1),wz=get(mx[x][p],mx[y-(1<

BZOJ3956 Count(單調棧 線段樹)

傳送門 感覺這道題蘊含了一些十分巧妙的性質。可以發現好點對實際上很少,最多不超過2n個。當乙個點作為點對中的較小點的時候,最多只能和它左邊第乙個大於等於它的點以及它右邊第乙個大於等於它的點配對。維護乙個單調遞減的棧就可以求出所有的好點對。還可以發現對於一段詢問的區間,找出區間中最大的點的位置,那麼區...

bzoj3956 Count 單調棧 st表

bzoj 非常巧妙的一道題 類似 hnoi影魔 每個點會給左右第乙個大於它的點對產生貢獻 可以用單調棧求出 這裡有點小細節,就是處理相等的點時,最左邊的點管左邊的貢獻,最右邊的點管最右邊的貢獻 然後對於每個點,求出了一對 x,y 那麼,對於詢問區間 l,r 答案就是有多少個 x,y 在區間 l,r ...

BZOJ3956 Count 主席樹 單調棧

3 2 0 2 1 2 1 11 303 m,n 3 10 5,ai 10 9 題解 影魔那道題的簡化版,依舊用單調棧記錄每個數左 右 邊第乙個比它大的數為ld i rd i 那麼合法的點對只有 i,i 1 和 ld i rd i 兩種。為了防止重複,我們記錄每個數左邊第乙個 它的數le i 當且僅...