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

来源:互联网 发布:飞天侠淘宝客9.0开源 编辑:程序博客网 时间:2024/04/28 16:07

用线段树保存当前区间里最近的蛋糕位置。

几个细节值得注意: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 999999999int 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];elsesite[rt]=site[rt*2];}elsesite[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]++;elsenum[rt]--;if(num[rt]==0) site[rt]=inf;elsesite[rt]=value;return ;}int m=(l+r)/2;if(index<=m) update(index,value,lson,op);elseupdate(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);}}


 

原创粉丝点击