1. 程式人生 > >HDU 1540 Tunnel Warfare

HDU 1540 Tunnel Warfare

alt return 圖片 stk 還要 sca stream tac ++

需要用線段樹維護區間的3個變量:

區間最長的:[左連續前綴、右連續後綴、最大連續子區間] 的元素個數

技術分享圖片

其中紅線左側的是第m個元素,右側是m+1個元素。

更新完左右子樹想要pushUp操作的時候,父親的左前綴必然是左子的前綴,若是左子樹滿了,則左連續可能還要加上右子樹的左前綴。同理,父親的右後綴必然是右子的後綴,若是右子都連續,那麽還要加上左子的後綴。

查詢的時候,若是位置p在左子的“橙色“部分,即後綴中,那麽結果應當是左子中的連續部分+(m+1)(即m的下一個元素)在右子的連續部分,同理p在右子的紫色部分時,要考慮加上左子的後綴部分。

代碼:

//
#include <bits/stdc++.h> #include <algorithm> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <stack> using namespace std; #define ll long long #define mst(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for (ll i = (a); i < (b); ++i) const
int inf = 0x3f3f3f3f, maxN = 5e4 + 7; int N, M, T; int stk[maxN]; #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 #define lch rt << 1 #define rch rt << 1 | 1 // 最長左連續前綴 右後綴 區間最大連續子區間 int lm[maxN << 2], rm[maxN << 2], mm[maxN << 2];
void init(int l, int r, int rt) { lm[rt] = rm[rt] = mm[rt] = r - l + 1; if (l == r) return; int m = (l + r) >> 1; init(lson); init(rson); } void update(int p, int x, int l, int r, int rt) { if (l == r) { lm[rt] = rm[rt] = mm[rt] = x; return; } int m = (l + r) >> 1; if (p <= m) update(p, x, lson); else update(p, x, rson); lm[rt] = lm[lch]; rm[rt] = rm[rch]; mm[rt] = max(max(lm[lch], rm[rch]), lm[rch] + rm[lch]); if (lm[lch] == m - l + 1) lm[rt] += lm[rch]; if (rm[rch] == r - m) rm[rt] += rm[lch]; } int query(int p, int l, int r, int rt) { if (mm[rt] == r - l + 1 || mm[rt] == 0 || l == r) return mm[rt]; int m = (l + r) >> 1; if (p <= m) { if (p >= m - rm[lch] + 1) return query(p, lson) + query(m + 1, rson); else return query(p, lson); } else { if (p <= m + lm[rch]) return query(p, rson) + query(m, lson); else return query(p, rson); } } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif while (~scanf("%d%d", &N, &M)) { char op[10]; int a; int idx = 0; init(1, N, 1); rep(i, 0, M) { scanf("%s", op); if (op[0] == R) { update(stk[--idx], 1, 1, N, 1); continue; } scanf("%d", &a); if (op[0] == Q) { printf("%d\n", query(a, 1, N, 1)); } else { update(a, 0, 1, N, 1); stk[idx++] = a; } } } return 0; }

HDU 1540 Tunnel Warfare