题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540
题目:
题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的村庄相连接的城市数量。
思路:线段树+区间合并。
代码实现如下:
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define bug printf("*********\n");
#define FIN freopen("D://code//in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = 1e8;
const int maxn = 5e4 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-') f = -, c = getchar();
for(; isdigit(c); c = getchar()) ret = ret * + c - '';
if(f < ) ret = -ret;
return ret;
} int n, q, x, t;
char op[];
int tack[maxn]; struct node {
int l, r, mx, ls, rs; //ls为左端最大连续区间,rs为右端最大连续区间,mx为区间内最大连续区间
}segtree[maxn*]; void build(int i, int l, int r) {
segtree[i].l = l, segtree[i].r = r;
segtree[i].mx = segtree[i].ls = segtree[i].rs = r - l + ;
if(l == r) return;
int mid = (l + r) >> ;
build(lson);
build(rson);
} void update(int i, int pos, int x) {
if(segtree[i].l == segtree[i].r) {
if(x == ) segtree[i].mx = segtree[i].ls = segtree[i].rs = ; //此处为修复操作
else segtree[i].mx = segtree[i].ls = segtree[i].rs = ; //摧毁操作
return;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(pos <= mid) {
update(i * , pos, x);
} else {
update(i * + , pos, x);
}
segtree[i].ls = segtree[i*].ls;
segtree[i].rs = segtree[i*+].rs;
segtree[i].mx = max(max(segtree[i*].mx, segtree[i*+].mx), segtree[*i].rs + segtree[i*+].ls);
if(segtree[i*].ls == segtree[i*].r - segtree[i*].l + ) { //如果左端全是连接的,那么ls还要右子树的ls
segtree[i].ls += segtree[i*+].ls;
}
if(segtree[i*+].rs == segtree[i*+].r - segtree[i*+].l + ) { //同理
segtree[i].rs += segtree[i*].rs;
}
} int query(int i, int pos) {
if(segtree[i].l == segtree[i].r || segtree[i].mx == segtree[i].r - segtree[i].l + || segtree[i].mx == ) {
return segtree[i].mx;
}
int mid = (segtree[i].l + segtree[i].r) >> ;
if(pos <= mid) {
if(pos >= segtree[*i].r - segtree[i*].rs + ) { //如果pos与右边连接,那么还需要跑另一棵子树
return query(i * , pos) + query(i * + , mid + );
} else {
return query(i * , pos);
}
} else {
if(pos <= segtree[i * + ].l + segtree[i*+].ls - ) { //同理
return query(i * + , pos) + query(i * , mid);
} else {
return query(i * + , pos);
}
}
} int main() {
//FIN;
while(~scanf("%d%d", &n, &q)) {
build(, , n);
t = ;
while(q--) {
scanf("%s", op);
if(op[] == 'D') {
scanf("%d", &x);
tack[++t] = x;
update(, x, );
} else if(op[] == 'R') {
if(t > ) {
x = tack[t--];
update(, x, );
}
} else {
scanf("%d", &x);
printf("%d\n", query(, x));
}
}
}
return ;
}