牛客練習賽69E 子串 樹狀陣列

2021-10-09 09:33:43 字數 1420 閱讀 1813

給出乙個n

nn的排列,求有多少個區間[l,

r]

[l,r]

[l,r

]使得最大值是r

rr,最小值是lll。

首先對於乙個位置的值作為左端點和右端點都有一段合法區間(到左邊第乙個比他小的和右邊第乙個比他大的,當右端點時同理)。可以用樹狀陣列預處理每個的合法區間

然後對於兩個點各作為左右端點需要滿足左端點在右端點的合法區間內,右端點在左端點的合法區間內。

那麼有演算法就是對於每個右端點我們在他合法區間的左邊壓入,右邊彈出然後指標掃瞄作為左端點的值進行區間查詢即可。

時間複雜度o(n

log⁡n)

o(n\log n)

o(nlogn)

#include

#include

#include

#include

#define lowbit(x) (x&-x)

using

namespace std;

const

int n=

1e6+10;

int n,p[n]

,la[n]

,ra[n]

,lp[n]

,rp[n]

,num[n]

;vector<

int> ql[n]

,qr[n]

;long

long ans;

struct tree_array

return;}

intask

(int x)

return ans;

}}ta,tp;

struct ttree_array

return;}

intask

(int x)

return ans;

}}t;

bool

cmp(

int x,

int y)

intmain()

memset

(ta.t,0,

sizeof

(ta.t));

memset

(tp.t,0,

sizeof

(tp.t));

for(

int i=n;i>=

1;i--

)for

(int i=

1;i<=n;i++)if

(p[i]

>=i&&ra[i]

&&p[i]

)sort

(num+

1,num+

1+n,cmp)

;for

(int i=

0;i<=n;i++

)printf

("%lld"

,ans)

;}

牛客練習賽69 E 字串 雜湊

給出乙個長度為n排列p 規定乙個區間 l,r l r 是 fair 的,當且僅當區間中最小值等於 l 並且最大值等於 r 求 fair 區間的個數 我不會正解 首先把每乙個i值對映成 base i 遍歷一邊全排列 然後每次加上base a i 減去base i 求貢獻,如果 l,r 滿足條件,那麼這...

牛客練習賽 69

第一次打牛客直接。y1s1牛客的評測系統真的慢,搞得我不想交 題目鏈結 首先先對陣列a逆序貪心可得val i,j a1 a2 ai j val i,j a 1 a 2 dots a val i,j a 1 a 2 ai j 嘗試證明 分析可知我們最終會選擇i j i ji j個陣列a的數,貪心肯定每...

牛客練習賽9 E 子串 轉移 掃瞄線 樹狀陣列

傳送門 感覺非常不好寫,我果然討厭資料結構 預處理l i l i l i 表示左邊第乙個大於i ii的下標加一 預處理r i r i r i 表示右邊第乙個小於i ii的下標減一 轉移方程是 for int i 1 i n i 作為右端點時,找左邊第乙個比i大的數字 pos i pos i pos ...