您的位置:首页 > 大数据 > 人工智能

2012 Multi-University Training Contest 1 Holedox Eating(线段树)

2012-07-21 20:53 555 查看
用线段树保存当前区间里最近的蛋糕位置。

几个细节值得注意:1、每次吃完蛋糕后要更新当前所在位置和前一个吃蛋糕的位置,以便在遇到有多个蛋糕距离一样的时候选择按原来方向吃一个蛋糕。

2、一个点可能有多个蛋糕,所以每次吃一个点的蛋糕后,该点蛋糕数减1,如果蛋糕数为0,则把该点值设为INF,否则该点值不变。

#include <stdio.h>
#include <string.h>
#define maxn 100050
#define lson l , m , rt *2
#define rson m+1 , r , rt *2 +1
#define dem int m = (l + r) / 2
#define inf 999999999
int site[maxn*4];
int num[maxn*4];
int n,m;
int now,pre;
int min(int x,int y)
{
return x<y?x:y;
}
int abs(int x)
{
return x<0?0-x:x;
}
void PushUp(int rt)
{
if(abs(site[rt*2]-now)==abs(site[rt*2+1]-now))
{
if(pre<now)
site[rt]=site[rt*2+1];
else
site[rt]=site[rt*2];
}
else
site[rt]=abs(site[rt*2]-now) < abs(site[rt*2+1]-now) ? site[rt*2] : site[rt*2+1];
}
void build(int l,int r,int rt)
{
site[rt]=inf;
if(l==r)	return ;
int m=(l+r)/2;
build(lson);
build(rson);
}
void update(int index,int value,int l,int r,int rt,int op)
{
if(l==r)
{
if(op==1)
num[rt]++;
else
num[rt]--;
if(num[rt]==0) site[rt]=inf;
else	site[rt]=value;
return ;
}
int m=(l+r)/2;
if(index<=m) update(index,value,lson,op);
else	update(index,value,rson,op);
PushUp(rt);
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
int T,ncase,a,b,i;
scanf("%d",&T);
ncase=1;
while(T--)
{
printf("Case %d: ",ncase++);
scanf("%d%d",&n,&m);
now=0;
pre=0;
memset(num,0,sizeof(num));
build(0,n,1);

int ans=0;
for(i=1;i<=m;i++)
{
scanf("%d",&a);

if(a==0){
scanf("%d",&b);
update(b,b,0,n,1,1);
}
else{
if(site[1]==inf)
continue;
ans+=abs(site[1]-now);
pre=now;
now=site[1];
update(now,now,0,n,1,0);
}
}
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: