POJ2892 Tunnel Warfare
Example Problems segment tree collection
The meaning of problems: there is a chain attached to adjacent nodes (1 and 2,2 and 3, ... n-1 and n are connected), there are three modes of operation: 1, destruction of a node 2, from a certain point Q. how many points to that point with no damaged (including their own) 3, is currently rebuilding a ruined last point
Establishing maintenance segment tree can reach every point around the boundary (the initial values are 1, n), when a damage point k (k is provided to reach the left and right borders of l1, r1), the interval l1 to k-1 the right boundary is modified to point k, k the left boundary point in the interval 1 + r1 to modify k
A sequence that disrupts the stack memory point, a reconstruction point, remove the top of the stack p (p is provided to reach the left and right boundaries of l2, R2), the right boundary point in the section k-1 l2 to modify r2, the left boundary point in the interval k + 1 to be modified to l2 r2
Directly query about +1 to the boundary and then subtract
(Konjac code may not be highly readable, but the main part is quite clear)
#include <stdio.h>
#include <iostream>
using namespace std;
inline void read (int &x) {
char ch = getchar(); x = 0;
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
}
void print (int x) {
if (x > 9) print (x / 10);
putchar (x % 10 + 48);
}
const int N = 5e4 + 10;
int n, m, x, top, st[N], ll[N], rr[N], k[N], cl[N << 3], cr[N << 3];
char ch[5];
#define ls p << 1
#define rs p << 1 | 1
inline void push_down (int p) {
if (cl[p]) cl[ls] = cl[rs] = cl[p], cl[p] = 0;
if (cr[p]) cr[ls] = cr[rs] = cr[p], cr[p] = 0;
}
void build (int p, int l, int r) {
if (l == r) {cl[l] = 1, cr[l] = n; return;}
int mid (l + r >> 1);
build (ls, l, mid), build (rs, mid + 1, r);
}
void update1 (int p, int l, int r, int ql, int qr, int v) { //修改右边界
if (ql <= l && qr >= r) {cr[p] = v; return;}
if (l == r) {rr[l] = cr[p]; return;}
push_down (p);
int mid (l + r >> 1);
if (ql <= mid) update1 (ls, l, mid, ql, qr, v);
if (qr > mid) update1 (rs, mid + 1, r, ql, qr, v);
}
void update2 (int p, int l, int r, int ql, int qr, int v) { //修改左边界
if (ql <= l && qr >= r) {cl[p] = v; return;}
if (l == r) {ll[l] = cl[p]; return;}
push_down (p);
int mid (l + r >> 1);
if (ql <= mid) update2 (ls, l, mid, ql, qr, v);
if (qr > mid) update2 (rs, mid + 1, r, ql, qr, v);
}
void query (int p, int l, int r, int pos) { //使这个点的所有懒标记更新(更新为真实值)
if (l == r) {ll[l] = cl[p], rr[l] = cr[p]; return;}
push_down (p);
int mid (l + r >> 1);
pos <= mid ? query (ls, l, mid, pos) : query (rs, mid + 1, r, pos);
}
int main() {
read (n), read (m);
build (1, 1, n);
for (int i = 1; i <= n; ++i) ll[i] = 1, rr[i] = n;
while (m--) {
scanf ("%s", ch);
if (ch[0] == 'D') {
read (x);
st[++top] = x, k[x] = 1, query (1, 1, n, x);
update1 (1, 1, n, ll[x] - (ll[x] != 1), x - 1, x - 1);
update2 (1, 1, n, x + 1, rr[x] + (rr[x] != n), x + 1);
}
else if (ch[0] == 'Q') {
read (x);
if (k[x]) puts ("0");
else query (1, 1, n, x), print (rr[x] - ll[x] + 1), puts ("");
}
else {
if (!top) continue;
x = st[top--], k[x] = 0, query (1, 1, n, x);
update1 (1, 1, n, ll[x] - (ll[x] != 1), x - 1, rr[x]);
update2 (1, 1, n, x + 1, rr[x] + (rr[x] != n), ll[x]);
}
}
return 0;
}