1.题面
http://acm.hdu.edu.cn/showproblem.php?pid=1540
2.题意
给定一条线段长度为n个单位,有m个操作,x为一个数字
D x:将数组上某个点设置为断点
Q x:询问x点所在的区间的的长度,如果x是断点,长度为0
R :撤销上一个D操作
3.解题思路
我百度了一下,发现前几页都是用线段树做的,当时我是震惊的,这也用得着线段树!!!
我是直接用set做的,首先设置0,n+1为哨兵插入set中,
D就是将x插入set中
Q就是upper_bound(x),找到第一个比x大的,然后迭代器向前移动一个单位,找到上一个断点,两者相减即是答案
R将上一个操作中的x删除就好,我用stack完成这个记录
4.解题代码
/*****************************************************************
> File Name: tmp.cpp
> Author: Uncle_Sugar
> Mail: uncle_sugar@qq.com
> Created Time: 2016年03月31日 星期四 17时21分08秒
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;
const int debug = 1;
const int size = 5000 + 10;
const int INF = INT_MAX>>1;
typedef long long ll;
set<int> st;
stack<int> stk;
void Destroy(){
int x;
cin >> x;
st.insert(x);
stk.push(x);
}
void Query(){
int x;
cin >> x;
set<int>::iterator begin,end;
end = begin = st.upper_bound(x);
begin--;
if (*begin==x)
cout << 0 << '\n';
else
cout << (*end) - (*begin) - 1 << '\n';
}
void Rebuild(){
int x = stk.top();
stk.pop();
st.erase(x);
}
int main()
{
std::ios::sync_with_stdio(false);cin.tie(0);
int i,j;
int n,m;
while (cin >> n >> m){
st.clear();
while (!stk.empty())
stk.pop();
st.insert(0);
st.insert(n+1);
while (m--){
char cmd[10];
cin >> cmd;
switch(cmd[0]){
case 'D':Destroy();break;
case 'Q':Query();break;
case 'R':Rebuild();break;
}
}
}
return 0;
}