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; }