在0~n长的管子里面吃蛋糕,0操作代表在某个点放蛋糕,1代表吃掉离他最近的蛋糕,当距离狗相同时,吃原来方向的蛋糕,要求求步数,起始点在0.
想不到线段树呢,,大神一提醒最大值和最小值,我才知道怎么用线段树解决,,表示题目看不懂呢,吃原来的方向,,,题目看不懂,呜呜
#include<iostream>
using namespace std;
const int MAX=100001;
const int INF=0x7fffffff;
int f=1;
struct T
{
int l,r,m,imax,imin;
int num;
}tree[MAX*3];
void Build_tree(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
tree[root].m=(l+r)>>1;
tree[root].imax=tree[root].imin=-1;//表示不存在
tree[root].num=0;
if(l==r) return ;
Build_tree(root<<1,l,tree[root].m);
Build_tree(root<<1|1,tree[root].m+1,r);
}
void Query(int root,int &st,int &dis)//dis=1
{
if(tree[root].imin==-1) return ;
if(tree[root].l==tree[root].r)
{
tree[root].num--;
dis+=abs(tree[root].l-st);
st=tree[root].l;//更新起始位置
if(tree[root].num==0)
{
tree[root].imax=tree[root].imin=-1;
}
return ;
}
if(tree[root<<1|1].imin!=-1&&tree[root<<1|1].imin<=st)//果断在右边的
{
Query(root<<1|1,st,dis);
}
else if (tree[root<<1].imax>=st)//果断在左边
{
Query(root<<1,st,dis);
}
else
{
int temp1,temp2;
if(tree[root<<1].imax==-1)
temp1=INF;
else
temp1=st-tree[root<<1].imax;
if(tree[root<<1|1].imin==-1)
temp2=INF;
else
temp2=tree[root<<1|1].imin-st;
if (temp1<temp2)
{
Query(root<<1,st,dis);
f=0;
}
else if(temp2<temp1)
{
Query(root<<1|1,st,dis);
f=1;
}
else
{
if(f==0)//左边
Query(root<<1,st,dis);
else
Query(root<<1|1,st,dis);
}
}
tree[root].imax=max(tree[root<<1|1].imax,tree[root<<1].imax);
tree[root].imin=INF;
if(tree[root<<1].imin!=-1&&tree[root<<1].imin<tree[root].imin)
tree[root].imin=tree[root<<1].imin;
if(tree[root<<1|1].imin!=-1&&tree[root<<1|1].imin<tree[root].imin)
tree[root].imin=tree[root<<1|1].imin;
if(tree[root].imin==INF)
tree[root].imin=tree[root].imax;
}
void Updata(int root,int point)
{
if(tree[root].r==tree[root].l)
{
tree[root].imax=tree[root].imin=point;
tree[root].num++;
return ;
}
if(point<=tree[root].m)
Updata(root<<1,point);
else
Updata(root<<1|1,point);
tree[root].imax=max(tree[root<<1|1].imax,tree[root<<1].imax);
tree[root].imin=INF;
if(tree[root<<1].imin!=-1&&tree[root<<1].imin<tree[root].imin)
tree[root].imin=tree[root<<1].imin;
if(tree[root<<1|1].imin!=-1&&tree[root<<1|1].imin<tree[root].imin)
tree[root].imin=tree[root<<1|1].imin;
if(tree[root].imin==INF)
tree[root].imin=tree[root].imax;
}
int main()
{
int t,l,n,m;
scanf("%d",&t);
int tt=1;
while(t--)
{
int st=0;
int dis=0;
scanf("%d%d",&l,&n);
Build_tree(1,0,l);
while(n--)
{
scanf("%d",&m);
if(m==1)//
{
Query(1,st,dis);
}
else
{
scanf("%d",&m);
Updata(1,m);
}
}
printf("Case %d: %d\n",tt++,dis);
}
return 0;
}