当前位置: 代码迷 >> 综合 >> hdu 1540(线段树)
  详细解决方案

hdu 1540(线段树)

热度:92   发布时间:2023-12-23 11:09:18.0

 

 

 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少。

线段树区间合并基础题。

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 5e4 + 10;
struct Tree
{int l, r;int ls, rs, ms;
}tree[maxn << 2];
int n, m;
int st[maxn];void build(int rt, int l, int r)
{tree[rt].l = l;tree[rt].r = r;tree[rt].ls = tree[rt].rs = tree[rt].ms = r - l + 1;if(l == r)  return;int mid = l + r >> 1;build(rt << 1, l, mid);build(rt << 1|1, mid + 1, r);
}void update(int rt, int pos, int val)
{if(tree[rt].l == tree[rt].r){if(val == 0)tree[rt].ls = tree[rt].rs = tree[rt].ms = 0;elsetree[rt].ls = tree[rt].rs = tree[rt].ms = 1;return;}int mid = tree[rt].l + tree[rt].r >> 1;if(pos <= mid)update(rt << 1, pos, val);elseupdate(rt << 1|1, pos, val);//pushup(rt);tree[rt].ls = tree[rt << 1].ls;tree[rt].rs = tree[rt << 1|1].rs;tree[rt].ms = max(max(tree[rt << 1].ls, tree[rt << 1|1].rs), tree[rt << 1].rs + tree[rt << 1|1].ls);if(tree[rt << 1].ls == tree[rt << 1].r - tree[rt << 1].l + 1)tree[rt].ls += tree[rt << 1|1].ls;if(tree[rt << 1|1].rs == tree[rt << 1|1].r - tree[rt << 1|1].l + 1)tree[rt].rs += tree[rt << 1].rs;
}int query(int rt, int pos)
{if(tree[rt].l == tree[rt].r || tree[rt].ms == 0 || tree[rt].ms == tree[rt].r - tree[rt].l + 1)          //importancereturn tree[rt].ms;int mid = tree[rt].l + tree[rt].r >> 1;if(pos <= mid){if(pos >= tree[rt << 1].r - tree[rt << 1].rs + 1)return query(rt << 1, pos) + query(rt << 1|1, mid + 1);elsereturn query(rt << 1, pos);}else{if(pos <= tree[rt << 1|1].l + tree[rt << 1|1].ls - 1)return query(rt << 1, mid) + query(rt << 1|1, pos);elsereturn query(rt << 1|1, pos);}
}int main()
{cin >> n >> m;char s[5];int x;int top = 0;build(1, 1, n);for(int i = 0; i < m; i++){scanf("%s", s);if(s[0] == 'D'){scanf("%d", &x);update(1, x, 0);st[top++] = x;}else if(s[0] == 'Q'){scanf("%d", &x);printf("%d\n", query(1, x));}else{int t = st[--top];update(1, t, 1);}}return 0;
}