這個是動態的,所以要用線段樹維護。**裡有注釋因為ls敲成lsum,rs敲成rsum查錯查了好久。。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include
10 #include 11 #include 12 #include 13 #include 14 #include 15
using
namespace
std;
16 typedef unsigned long
long
ull;
17 typedef long
long
ll;18
const
int inf = 0x3f3f3f3f;19
const
double eps = 1e-8
;20 template
21 inline bool scan_d(t &ret)
2235
36const
int maxn = 1e5+10;37
int ls[maxn<<2],rs[maxn<<2]; //
ls為區間左值,rs為區間右值 比較時要用到。
38int lsum[maxn<<2],rsum[maxn<<2],sum[maxn<<2]; //
lsum為區間左上公升長度,rsum為區間右上公升長度,sum為區間最大上公升長度。
3940
void push_up(int l,int r,int
pos)
4156}57
58void build (int l,int r,int
pos)
5969
int mid =(l + r) >> 1
;70 build(l,mid,pos<<1
);71 build(mid+1,r,pos<<1|1
);72
push_up(l,r,pos);73}
7475
void update(int l,int r,int pos,int x,int
val)
7682
int mid = (l + r) >> 1;83
if (x <=mid)
84 update(l,mid,pos<<1
,x,val);
85else
86 update(mid+1,r,pos<<1|1
,x,val);
87push_up(l,r,pos);88}
8990
91int query(int l,int r,int pos,int ua,int
ub)92
97int mid = (l + r) >> 1;98
int ans1 = 0,ans2 = 0,ans3 = 0;99
if (ua <=mid)
100 ans1 = query(l,mid,pos<<1
,ua,ub);
101if (ub >mid)
102 ans2 = query(mid+1,r,pos<<1|1
,ua,ub);
103if (ls[pos<<1|1] > rs[pos<<1
])104 ans3 = min(lsum[pos<<1|1],ub-mid) + min(rsum[pos<<1],mid-ua+1
);105
return
max(ans1,max(ans2,ans3));
106}
107108
109int main(void
)110
131}
132return0;
133 }
HDU 3308 LCIS 線段樹,連續遞增子
by cxlove 題目 給出乙個序列,兩種操作,單點更新值,以及查詢區間的最長連續遞增子串行長度 這題比較簡單,如果是求最長遞增子串行長度就難了,不需要連續就是簡單的區間合併類的線段樹了。每乙個結點要記錄包含左端點的最長連續遞增子長度,包含右端點的最長連續遞增子長度,以及整個區間的最長遞增子長度,...
HDU 3308 LCIS(線段樹合併)
維護乙個區間的包含最左的元素的lcis,包含最右元素的lcis,以及整個區間的lcis,然後pushup的時候就更新這三個值就行了。注意要考慮左右兒子可以 接 起來的情況等等 查詢的時候要注意,也要考慮左右可以 接 起來時候,不過還要注意,有可能左右兒子邊界的已經 越界了 就是超過了查詢範圍,還要取...
HDU 3308 LCIS(線段樹區間合併)
給你乙個序列,現在進行一些操作,一種是詢問某一段最長連續上公升子串行 lcis 的長度,另乙個就是修改某個點的值 區間合併的簡單題 這裡的區間合併,要判斷的是左兒子最右邊的值和右兒子最左邊的值的關係,那麼我們這道題要維護的東西就有 最左端開始的lcis,包括最右端的lcis,該區間的lcis,最左邊...