乙個區間合法當且僅當 max
_v−m
in_v
==r−
lmax
_v−m
in_v
==r−
l, 移項得 min
_v==
max_
v−(r
−l)m
in_v
==ma
x_v−
(r−l
),可以想到列舉 min
_v=a
[i]m
in_v
=a[i
], 記錄左邊第乙個比 i
i 小的位置和右邊第乙個比 i
i 小的位置,
分別記為 ld[
i],r
d[i]
ld[i
],rd
[i], 然後在 (ld
[i],
rd[i
])(l
d[i]
,rd[
i]) 中列舉 左端點屬於 (ld
[i],
p](l
d[i]
,p], 右端點屬於 (p,
rd[i
])(p
,rd[
i]),
直接裸算時間複雜度期望 o(n
log2n
)o(n
log2n)
,加上列舉右端點時的 「可行性剪枝」, 和對 ∣a[
i]−a
[i+1
]∣=1
∣a[i
]−a[
i+1]
∣=1 連續數字的加速, 跑隨機資料 0.3s0
.3s 可出答案 .co
deco
de從左向右列舉右端點 r
r, 檢查 r
r 的左邊有多少 l
l 滿足 r=m
ax_v
−min
_v+l
r=ma
x_v−
min_
v+l,
其中 max
_v,m
in_v
max_
v,mi
n_v 都是在 [l,
r][l
,r] 區間意義下的,
考慮 r
r 向右移動一位對 l∈[
1,r+
1]l∈
[1,r
+1] 的影響,
此時 a[r
+1]a
[r+1
] 可能成為關於 [l,
r+1]
[l,r
+1] 的新的最大值, 也可能成為新的最小值,
而影響的區間又是連續的, 考慮使用單調棧維護,具體
來說具體
來說: 以維護最大值為例, 建立乙個單調遞減的單調棧,棧中存下標,
在彈出棧頂時在線段樹中更新棧頂與次棧頂的差大小的左端點們代表的區間 .
單調遞增的單調棧也按此方法維護最小值.
對於 r
r, 統計線段樹的區間 [1,
r][1
,r] 中有多少最小值等於 r
r 即可 .
#include
#define reg register
intread()
while
(isdigit
(c)) s = s*
10+ c-
'0', c =
getchar()
;return s * flag;
}const
int maxn =
300005
;int n;
int top[2]
;int a[maxn]
;int stk[2]
[maxn]
;struct segment_tree t[maxn<<3]
;void
push_up
(int k)
void
build
(int k,
int l,
int r)
int mid = l+r >>1;
build
(k<<
1, l, mid)
,build
(k<<1|
1, mid+
1, r)
,push_up
(k);
}void
push_down
(int k)
void
modify
(int k,
const
int&ql,
const
int&qr,
const
int&v)
int mid = l+r >>1;
modify
(k<<
1, ql, qr, v)
,modify
(k<<1|
1, ql, qr, v)
;push_up
(k);
}int
query
(int k,
const
int&ql,
const
int&qr)
int mid = l+r >>
1, s =0;
if(ql <= mid) s +
=query
(k<<
1, ql, qr);if
(qr > mid) s +
=query
(k<<1|
1, ql, qr)
;return s;
}} seg_t;
intmain()
stk[0]
[++ top[0]
]= r;
while
(top[1]
&& a[stk[1]
[top[1]
]]< a[r]
) stk[1]
[++ top[1]
]= r;
ans +
= seg_t.
query(1
,1, r);}
printf
("%lld\n"
, ans)
;return0;
}
線段樹維護連續區間
在抗日戰爭期間,華北平原廣大地區進行了大規模的隧道戰。一般來說,通過隧道連線的村莊排成一列。除了兩端,每個村莊都與兩個相鄰的村莊直接相連。入侵者經常對一些村莊發動襲擊並摧毀其中的部分隧道。八路軍指揮官要求最新的隧道和村莊連線狀態。如果某些村莊嚴重隔離,必須立即恢復連線!input 輸入的第一行包含兩...
線段樹區間合併 連續區間問題
hdu 1540 資料很奇葩。用討論區裡面的話形容這題很合適 九九八十一難,這道題比北大的資料真是坑出翔來了 poj 2892 原題 一摸一樣 題意 給定n個村莊排成一行,它們相鄰的村莊通過地道相連,有三種操作 1 炸毀第x個村莊 2 修復上乙個被炸毀的村莊 3 詢問 輸出 第x個村莊還能和幾個村莊...
線段樹3(離散化,連續區間)
題目是依次按給定的範圍貼海報,問覆蓋到最後還能看到幾張海報。因為給定的貼海報的板子總長度為10 9,陣列開不下。但是考慮到海報只有10 5張,而整個問題其實課忽略板子長度,只需要考慮每張海報之間的覆蓋關係就可以了,也就是說 1,1000008 3,9990 10,20000000 這三個區間的覆蓋情...