資料結構 線段樹 2018國慶三校聯考D5T3

2021-08-28 19:01:38 字數 1924 閱讀 5851

有乙個顯然的暴力方法:

對每個詢問,從左往右做一次,記錄字首和,當某個位置字首和為負後,則刪去當前點。再從右往左做一次。

考慮使這個過程變得高效:

可以將詢問按左端點從右往左排序,然後用棧依次處理每個在從左往右考慮時是否需要刪除。

再利用線段樹,求出沒有刪除的部分的最小字尾和,其相反數(和0取min)即為從右往左考慮時需要刪除的個數。

#include

#include

#include

#include

#define sf scanf

#define pf printf

#define maxn 500010

#define inf 0x3fffffff

using

namespace std;

typedef pair<

int,

int> pii;

struct node

}q[maxn]

;int tree[maxn*4]

,sum[maxn*4]

,ans[maxn]

;int st[maxn]

,top,n;

char s[maxn]

;void

change

(int pos,

int val,

int l=1,

int r=n,

int id=1)

int mid=

(l+r)

>>1;

if(pos<=mid)

change

(pos,val,l,mid,id<<1)

;else

change

(pos,val,mid+

1,r,id<<1|

1); tree[id]

=min

(tree[id<<1]

+sum[id<<1|

1],tree[id<<1|

1]);

sum[id]

=sum[id<<1]

+sum[id<<1|

1];}

pii que

(int l1,

int r1,

int l=1,

int r=n,

int id=1)

if(l1<=mid)

return

make_pair

(res,tmp1.second+tmp2.second);}

intbque

(int l,

int r,

int val)

else

l=mid+1;

}return top-res+1;

}int

main()

sort

(q+1

,q+1

+q);

int las=n;

for(

int i=q;i>=

1;i--

)else

las--;}

ans[q[i]

.id]

=bque(1

,top+

1,q[i]

.r)-

min(0,

(que

(q[i]

.l,q[i]

.r))

.first);}

for(

int i=

1;i<=q;i++)pf

("%d\n"

,ans[i]);

}/*11vvvccccccvv

31 11

4 91 6

*/

資料結構 線段樹

啦啦啦啦啦啦線段樹是個好東西 好吧並沒有什麼好的 但貌似還是很好啊 線段樹就是一棵樹!顧名思義 又是這個詞 就是求關於一段的某些什麼什麼東西。比如區間最大值啊什麼的。引用百科知識 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中...

資料結構 線段樹

一 目標 1.如何快速的查詢出下列陣列arr 2,5 的和 2。以及更新arr 4 為6。用普通的方法查詢的複雜度為o n 更新的複雜度為o 1 這時候我們可以用線段樹來快速完成這些操作,複雜度為logn。二 內容 如何建立,查詢,更新線段樹。public class qurqpd int tree...

資料結構 線段樹

線段樹是一顆平衡的二叉搜尋樹,他以空間換區時間,讓線性查詢加速log級別的查詢,用到的演算法主要是二分搜尋和遞迴。例如 有陣列data 我有乙個需求,我需要頻繁的查詢區間i j的sum和。這裡先給出兩個解決方案 如果使用最普通的演算法遍歷,那麼查詢和更新的複雜度為o n 當然你還可以使用動態規劃,定...