BZOJ1171 : 大sz的游戏

f[i]=min(f[j])+1,线段j与线段i有交,且l[i]-l[j]<=L。

线段j与线段i有交等价于y[j]>=x[i],x[j]<=y[i]。

因为l[i]递增,所以可以维护一个单调递增的j,表示[j,i-1]范围内都可以更新f[i]。

用k-d树动态维护即可,时间复杂度$O(n\sqrt{n})$。

 

#include<cstdio>

#include<algorithm>

const int N=250010,inf=2000000000;

int n,L,i,j,k,root,cmp_d,X,Y;

struct P{int x,y,l,f,p;}a[N];

inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}

struct node{int d[2],l,r,Max[2],Min[2],val,sum,f;}t[N];

inline bool cmp(node a,node b){return a.d[cmp_d]<b.d[cmp_d];}

inline void umax(int&a,int b){if(a<b)a=b;}

inline void umin(int&a,int b){if(a>b)a=b;}

inline void up(int x){

  t[x].sum=t[x].val;

  if(t[x].l){

    umin(t[x].sum,t[t[x].l].sum);

    umax(t[x].Max[0],t[t[x].l].Max[0]);

    umin(t[x].Min[0],t[t[x].l].Min[0]);

    umax(t[x].Max[1],t[t[x].l].Max[1]);

    umin(t[x].Min[1],t[t[x].l].Min[1]);

  }

  if(t[x].r){

    umin(t[x].sum,t[t[x].r].sum);

    umax(t[x].Max[0],t[t[x].r].Max[0]);

    umin(t[x].Min[0],t[t[x].r].Min[0]);

    umax(t[x].Max[1],t[t[x].r].Max[1]);

    umin(t[x].Min[1],t[t[x].r].Min[1]);

  }

}

inline void up2(int x){

  t[x].sum=t[x].val;

  if(t[x].l)umin(t[x].sum,t[t[x].l].sum);

  if(t[x].r)umin(t[x].sum,t[t[x].r].sum);

}

int build(int l,int r,int D,int f){

  int mid=(l+r)>>1;

  cmp_d=D,std::nth_element(t+l+1,t+mid+1,t+r+1,cmp);

  a[t[mid].f].p=mid;

  t[mid].f=f;

  t[mid].Max[0]=t[mid].Min[0]=t[mid].d[0];

  t[mid].Max[1]=t[mid].Min[1]=t[mid].d[1];

  if(l!=mid)t[mid].l=build(l,mid-1,!D,mid);

  if(r!=mid)t[mid].r=build(mid+1,r,!D,mid);

  return up(mid),mid;

}

inline void change(int x,int p){for(t[x].val=p;x;x=t[x].f)up2(x);}

void ask(int x){

  if(t[x].Min[0]>X||t[x].Max[1]<Y||t[x].sum>=k)return;

  if(t[x].Max[0]<=X&&t[x].Min[1]>=Y){k=t[x].sum;return;}

  if(t[x].d[0]<=X&&t[x].d[1]>=Y&&t[x].val<k)k=t[x].val;

  if(t[x].l)ask(t[x].l);

  if(t[x].r)ask(t[x].r);

}

int main(){

  read(n),read(L);

  a[1].x=0,a[1].y=inf;

  for(i=2;i<=n;i++)read(a[i].x),read(a[i].y),read(a[i].l),a[i].f=inf;

  for(i=1;i<=n;i++)t[i].d[0]=a[i].x,t[i].d[1]=a[i].y,t[i].val=a[i].f,t[i].f=i;

  root=build(1,n,0,0);

  for(i=2,j=1;i<=n;i++){

    while(a[i].l-a[j].l>L)change(a[j++].p,inf);

    k=inf,X=a[i].y,Y=a[i].x,ask(root);

    if(k<inf)change(a[i].p,a[i].f=k+1);

    printf("%d\n",a[i].f<inf?a[i].f:-1);

  }

  return 0;

}

  

你可能感兴趣的:(ZOJ)