hdu1540-Tunnel Warfare (线段树区间合并)

时间:2023-03-10 06:54:17
hdu1540-Tunnel Warfare       (线段树区间合并)

题意:n个村庄,有三种操作,D x 破坏位置为x的村庄,R 修复上一次被破坏的村庄,Q x 输出含有x村庄的连续村庄的最大个数。线段树搞之,区间合并。

ls[maxn]为当前节点左面的连续区间,rs[maxn]为当前节点左面的连续区间,ms[maxn]当前节点的最大连续区间。

 #include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 5e4+;
int ls[maxn<<],ms[maxn<<],rs[maxn<<];
stack<int>S;
void build(int l,int r,int pos)
{
ls[pos] = rs[pos] = ms[pos] = r - l + ;
if (l == r)
return;
int mid = (l + r) >> ;
build(l,mid,pos<<);
build(mid+,r,pos<<|);
}
void update(int l,int r,int pos,int x,int val)
{
if (l == r)
{
ls[pos] = rs[pos] = ms[pos] = val;
return;
}
int mid = (l + r) >> ;
if (x <= mid)
update(l,mid,pos<<,x,val);
if (x > mid)
update(mid+,r,pos<<|,x,val);
ms[pos] = max(rs[pos<<]+ls[pos<<|],max(ms[pos<<],ms[pos<<|]));
ls[pos] = ls[pos<<];
rs[pos] = rs[pos<<|];
if (mid-l+==rs[pos<<])
ls[pos] += ls[pos<<|];
if (r-mid==ls[pos<<|])
rs[pos] += rs[pos<<];
}
int query(int l,int r,int pos,int x)
{
if (ms[pos] == r - l + || !ms[pos] || l == r)
{
return ms[pos];
}
int mid = (l + r) >> ;
if (x <= mid)
{
if (x >= mid - rs[pos<<] + )
return query(l,mid,pos<<,x) + query(mid+,r,pos<<|,mid+);
else
return query(l,mid,pos<<,x);
}
else
{
if (x <= mid+ls[pos<<|])
return query(mid+,r,pos<<|,x) + query(l,mid,pos<<,mid);
else
return query(mid+,r,pos<<|,x);
}
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n,m;
while (~scanf ("%d%d",&n,&m))
{
build(,n,);
char op[];
for (int i = ; i < m; i++)
{
int x;
scanf ("%s",op);
if (op[] == 'D')
{
scanf ("%d",&x);
update(,n,,x,);
S.push(x);
}
if (op[] == 'Q')
{
scanf ("%d",&x);
printf("%d\n",query(,n,,x));
}
if (op[] == 'R')
{
if (!S.empty())
{
int tmp = S.top();
S.pop();
update(,n,,tmp,);
}
}
}
while (!S.empty())
S.pop();
}
return ;
}