洛谷__P1503 鬼子进村(树形数据结构)
题目链接:P1503 鬼子进村 - 洛谷
题目大意:
给定一个长为 的 序列 ,初始为全
有三种操作,
- 操作
D:修改 为 , - 操作
R:撤回一次最近的修改, - 操作
Q:给定 求第 个元素所在的全部是 的联通块的大小。
思路:
用 set 记录 1 的位置,
对于操作Q,就是找 set 中 第一个大于等于 x 的位置 - 第一个小于等于 x 的位置
对于操作R,用 stack 维护,弹出栈并在set中抹除掉 x
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#include<array>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/numeric>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
#define pb push_back
#define gmap __gnu_pbds::gp_hash_table
#define power __gnu_cxx::power
using namespace std;
typedef pair<int, int> pii;
const int N = 200086, mod = 998244353;
int n, m;
stack<int> st;
set<int> s;
void solve() {
cin >> n >> m;
s.insert(0), s.insert(n + 1);//初始化边界
while (m--) {
char c;
int x;
cin >> c;
if (c == 'D') {
cin >> x;
s.insert(x);
st.push(x);
} else if (c == 'Q') {
cin >> x;
auto it = s.lower_bound(x);
if (*it == x) {
cout << 0 << endl;
continue;
}
int res = *it - *(--it);
cout << res - 1 << endl;
} else {
int u = st.top();
st.pop();
s.erase(s.find(u));
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号