线段树区间合并
点击此处进入题目
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
const int N = 50010;
int temp[N];
struct node
{
int l,r,lmax,rmax,tmax;
}tr[N * 4];
void pushup(node &root ,node &left, node &right)
{
root.lmax = left.lmax;
root.rmax = right.rmax;
if(left.lmax == left.r - left.l + 1) root.lmax += right.lmax;
if(right.rmax == right.r - right.l + 1) root.rmax += left.rmax;
root.tmax = max(max(left.tmax , right.tmax), left.rmax + right.lmax);
}
void pushup(int u)
{
pushup(tr[u] , tr[u << 1], tr[u << 1 | 1]);
}
void build(int u,int l,int r)
{
if(l == r) tr[u] = {r , r, 1, 1, 1};
else
{
tr[u] = {l , r};
int mid = l + r >> 1;
build(u << 1, l , mid);
build(u << 1|1, mid + 1 , r);
pushup(u);
}
}
void modify(int u,int x,int c)
{
if(tr[u].l == x && tr[u].r == x) tr[u] = {x,x,c,c,c};
else
{
int mid = tr[u].l + tr[u].r >> 1;
if(x <= mid) modify(u << 1, x , c);
else modify(u << 1 | 1, x ,c);
pushup(u);
}
}
int query(int u,int x) {
if (tr[u].tmax == 0 || tr[u].l == tr[u].r) return tr[u].tmax;
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid)
{
if (mid - x + 1 <= tr[u << 1].rmax) return tr[u << 1].rmax + tr[u << 1 | 1].lmax;
else return query(u << 1, x);
}
else
{
if (x - mid <= tr[u << 1 | 1].lmax) return tr[u << 1].rmax + tr[u << 1 | 1].lmax;
else return query(u << 1 | 1, x);
}
}
signed main()
{
while(cin >> n >> m)
{
memset(temp,0,sizeof temp[0] * n);
memset(tr ,0 ,sizeof tr[0] * 4 * n);
build(1,1,n);
int cnt = 0;
while(m --)
{
char s; int x;
cin >> s;
if(s == 'D')
{
cin >> x;
modify(1,x,0);
temp[ ++ cnt] = x;
}
else if(s == 'Q')
{
cin >> x;
cout << query(1,x) << endl;
}
else if(cnt > 0) modify(1,temp[cnt --],1);
}
}
return 0;
}