有乙個顯然的暴力方法:
對每個詢問,從左往右做一次,記錄字首和,當某個位置字首和為負後,則刪去當前點。再從右往左做一次。
考慮使這個過程變得高效:
可以將詢問按左端點從右往左排序,然後用棧依次處理每個在從左往右考慮時是否需要刪除。
再利用線段樹,求出沒有刪除的部分的最小字尾和,其相反數(和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 當然你還可以使用動態規劃,定...