题意:每次find找到x和y均严格大于给定数值的点,优先找到x最小的,然后优先找到y最小的,如果没有这样的点就输出-1。
思路:首先离散化排序,使得x,y小的在前面(优先x),然后对于每个节点,记录其中存在的点的y的最大值,以及子节点的x的范围,最后查询。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
map<int,int> match;
char s[10];
int op[100010][2],f[100010];
struct node
{
int num,l,r;
ll M[6];
}tree[400010];
void build(int o,int l,int r)
{
tree[o].l=l;
tree[o].r=r;
tree[o].num=0;
memset(tree[o].M,0,sizeof(tree[o].M));
if(l==r)
return;
int mi=(l+r)/2;
build(o*2,l,mi);
build(o*2+1,mi+1,r);
}
void update(int o,int pos,int val,int f)
{
if(tree[o].l==pos && tree[o].r==pos)
{
if(f==1)
{
tree[o].num=1;
tree[o].M[1]=val;
}
else
{
tree[o].num=0;
tree[o].M[1]=0;
}
return;
}
int mi=(tree[o].l+tree[o].r)/2;
if(pos<=mi)
update(o*2,pos,val,f);
else
update(o*2+1,pos,val,f);
int i;
for(i=0;i<5;i++)
tree[o].M[i]=tree[o*2].M[i]+tree[o*2+1].M[(i-tree[o*2].num%5+5)%5];
tree[o].num=tree[o*2].num+tree[o*2+1].num;
}
int main()
{
int n,m,i,j,k;
while(~scanf("%d",&n))
{
for(i=1;i<=n;i++)
{
scanf("%s",s);
if(s[0]=='s')
op[i][0]=0;
else
{
if(s[0]=='a')
op[i][0]=1;
else
op[i][0]=-1;
scanf("%d",&k);
op[i][1]=k;
f[i]=k;
}
}
sort(f+1,f+1+n);
m=0;
match.clear();
for(i=1;i<=n;i++)
if(f[i]!=f[i-1])
{
m++;
match[f[i]]=m;
}
build(1,1,m);
for(i=1;i<=n;i++)
{
if(op[i][0]==0)
printf("%I64d\n",tree[1].M[3]);
else
update(1,match[op[i][1]],op[i][1],op[i][0]);
}
}
}