题意:有n个村庄,编号分别为1-n;由于战争会破坏村庄,但是我们也会修复;
D x代表村庄x被破坏;
Q x是求与x相连的有几个没有被破坏;
R 是修复最后一次被破坏的村庄;
接下来有m个操作,对于每次Q操作输出结果;
由于修复的是最后一次被破坏的所以要用stack
接下来看代码吧,加个图好理解一点
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<stack> #include<iostream> #define INF 0xfffffff #define N 50100 using namespace std; #define Lson r<<1 #define Rson r<<1|1 struct SegTree { int L, R; int s,ls,rs; //s代表L--R中最大连续个数,ls代表L开始所能没有破坏的连续个数;同理rs; int mid() { return (L+R)>>1; } int len() { return R-L+1; } }a[N*4]; void Update(int r, int x, int op) { if(a[r].L == a[r].R) { a[r].ls = a[r].rs = a[r].s = op; return; } if(x<=a[r].mid()) Update(Lson, x, op); else Update(Rson, x, op); a[r].ls = a[Lson].ls; a[r].rs = a[Rson].rs; if(a[Lson].ls == a[Lson].len()) a[r].ls = a[Lson].ls + a[Rson].ls; if(a[Rson].rs == a[Rson].len()) a[r].rs = a[Rson].rs + a[Lson].rs; a[r].s = max(a[Lson].rs + a[Rson].ls, max(a[Lson].ls, a[Rson].rs)); } void BuildSegTree(int r, int L, int R) { a[r].L = L, a[r].R = R; a[r].ls = a[r].rs = a[r].s = a[r].len(); if(L == R)return; BuildSegTree(Lson, L, a[r].mid()); BuildSegTree(Rson, a[r].mid()+1, R); } int Query(int r, int x) { if(a[r].s == 0) return 0; if(x < a[r].L + a[r].ls)//判断是否在左边 return a[r].ls; if(x > a[r].R - a[r].rs)//判断是否在右边 return a[r].rs; if(x > a[Lson].R - a[Lson].rs && x < a[Rson].L+a[Rson].ls) return a[Lson].rs + a[Rson].ls; if(x <= a[r].mid()) return Query(Lson, x); else return Query(Rson, x); } int main() { int n, m, x; char str[10]; stack<int>Q; while(scanf("%d%d", &n, &m) != EOF) { BuildSegTree(1, 1, n); while(m--) { scanf("%s", str); if(str[0] == ‘D‘) { scanf("%d", &x); Update(1, x, 0); Q.push(x); } else if(str[0] == ‘Q‘) { scanf("%d", &x); printf("%d\n", Query(1, x)); } else { Update(1, Q.top(), 1); Q.pop(); } } } return 0; }
时间: 2024-10-13 17:51:22