/*
分析:
线段树(其它方法也行)。
除了最低的一级节点储存该节点有几个cake,其它的节点
表示其所代表的区间内有没有cake。
有一点真心不明白了,为什么一定要开6倍的空间(60W)才
过,否则就数组越界,线段树开4倍的节点不就妥妥的够了么?
难道我理解有问题?还请路过的牛牛随手给个解释,谢了~
2012-12-11
*/
分析:
线段树(其它方法也行)。
除了最低的一级节点储存该节点有几个cake,其它的节点
表示其所代表的区间内有没有cake。
有一点真心不明白了,为什么一定要开6倍的空间(60W)才
过,否则就数组越界,线段树开4倍的节点不就妥妥的够了么?
难道我理解有问题?还请路过的牛牛随手给个解释,谢了~
2012-12-11
*/
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"math.h"
#define N 100011
int n,m;
struct Segtree
{
int l,mid,r;
int flag;
}T[6*N];
void build(int l,int r,int k)
{
T[k].l=l;
T[k].r=r;
T[k].mid=(l+r)>>1;
T[k].flag=0;
if(l==r) return ;
build(l,T[k].mid,2*k);
build(T[k].mid+1,r,2*k+1);
}
void update(int aim,int dir,int k)
{
if(T[k].l==T[k].r && T[k].l==aim) {T[k].flag+=dir;return ;}
if(aim<=T[k].mid) update(aim,dir,2*k);
else update(aim,dir,2*k+1);
T[k].flag=T[2*k].flag || T[2*k+1].flag;
}
int find_l(int l,int r,int k)
{
if(T[k].l==l && T[k].r==r && l==r)
{
if(T[k].flag) return l;
else return -1;
}
int ans=-1;
if(r<=T[k].mid && T[2*k].flag) ans=find_l(l,r,2*k);
else if(l>T[k].mid && T[2*k+1].flag)ans=find_l(l,r,2*k+1);
else
{
if(T[2*k+1].flag) ans=find_l(T[k].mid+1,r,2*k+1);
if(ans==-1 && T[2*k].flag) ans=find_l(l,T[k].mid,2*k);
}
return ans;
}
int find_r(int l,int r,int k)
{
if(T[k].l==l && T[k].r==r && l==r)
{
if(T[k].flag) return l;
else return -1;
}
int ans=-1;
if(r<=T[k].mid && T[2*k].flag) ans=find_r(l,r,2*k);
else if(l>T[k].mid && T[2*k+1].flag)ans=find_r(l,r,2*k+1);
else
{
if(T[2*k].flag) ans=find_r(l,T[k].mid,2*k);
if(ans==-1 && T[2*k+1].flag) ans=find_r(T[k].mid+1,r,2*k+1);
}
return ans;
}
int main()
{
int T,Case;
int a,b;
int pre,dire,sum;
scanf("%d",&T);
for(Case=1;Case<=T;Case++)
{
scanf("%d%d",&n,&m);
build(0,n,1);
sum=pre=0;
dire=1;
int x,temp;
while(m--)
{
scanf("%d",&x);
if(!x) {scanf("%d",&x),update(x,1,1);}
else
{
a=find_l(0,pre,1);
b=find_r(pre,n,1);
if(a==-1 && b==-1) continue;
if(a==-1) temp=b;
else if(b==-1) temp=a;
else
{
if(pre-a<b-pre) temp=a;
else if(pre-a>b-pre)temp=b;
else if(dire==1) temp=b;
else temp=a;
}
update(temp,-1,1);
if((temp-pre)*dire<0) dire*=-1;
sum+=abs(temp-pre);
pre=temp;
}
}
printf("Case %d: %d\n",Case,sum);
}
return 0;
}