您的位置:首页 > 其它

Sicily 1802 Atomic Nucleus Investigation(线段树)

2010-10-14 21:59 316 查看
新手赛的题目,让我回想起打酱油的时光

//线段树
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 100000000
using namespace std;
int T,M;
char cmd[10],n;
bool R[100005],G[100005];
struct seg
{
int l,r,_max,_min,delta;//记录最大值,最小值,最优差值,_max,_min为0表示不存在这个数
}tree[100005*4];
void update(int x)//回溯更新
{
tree[x]._max = max(tree[2*x]._max,tree[2*x+1]._max);
if(!tree[2*x]._min)	tree[x]._min = tree[2*x+1]._min;//如果左子树不存在最小值,就用右子树的最小值
else tree[x]._min = tree[2*x]._min;//否则去左子树的最小值
tree[x].delta = min(tree[2*x].delta,tree[2*x+1].delta);//取最优子树的最小差值
if(tree[2*x]._max && tree[2*x+1]._min)//左子树的最大值和右子树的最小值存在的话
tree[x].delta = min(tree[x].delta,tree[2*x+1]._min - tree[2*x]._max);
}
void buildTree(int x,int l,int r)
{
tree[x].l = l;
tree[x].r = r;
tree[x]._max = 0;
tree[x]._min = 0;
tree[x].delta = INF;
if(l == r)	return;
int mid = (l+r) >> 1;
buildTree(2*x,l,mid);
buildTree(2*x+1,mid+1,r);
}
void Insert(int x,int l,int r)
{
int mid = (tree[x].l + tree[x].r) >> 1;
if(tree[x].l == l && tree[x].r == r)
{
tree[x]._max = tree[x]._min = l;
return;
}
if(r <= mid)	Insert(2*x,l,r);
else if(l > mid)	Insert(2*x+1,l,r);
tree[x]._max = max(tree[2*x]._max,tree[2*x+1]._max);
if(!tree[2*x]._min)	tree[x]._min = tree[2*x+1]._min;
else tree[x]._min = tree[2*x]._min;
update(x);
}
void Remove(int x,int l,int r)
{
int mid = (tree[x].l + tree[x].r) >> 1;
if(tree[x].l == l && tree[x].r == r)
{
tree[x]._max = tree[x]._min = 0;
tree[x].delta = INF;
return;
}
if(r <= mid)	Remove(2*x,l,r);
else if(l > mid)	Remove(2*x+1,l,r);
update(x);
}
int Query(int x)//直接询问根结点就能得出结果
{
if(tree[x].delta == INF)
return -1;
else return tree[x].delta;
}

int main()
{
int x;
bool first = 1;
//freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
if(first)	first = 0;
else printf("/n");
buildTree(1,1,100000);
memset(R,0,sizeof(R));//标记是否remove过
memset(G,0,sizeof(G));//标记是否generate过
scanf("%d",&M);
while(M--)
{
scanf("%s",cmd);
if(cmd[0] == 'g')
{
scanf("%d",&x);
if(!G[x])
{
G[x] = 1;
Insert(1,x,x);
R[x] = 0;
}
}
if(cmd[0] == 'r')
{
scanf("%d",&x);
if(!R[x])
{
R[x] = 1;
Remove(1,x,x);
G[x] = 0;
}
}
if(cmd[0] == 'q')	printf("%d/n",Query(1));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: