zoukankan      html  css  js  c++  java
  • 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(nsqrt{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
    ",a[i].f<inf?a[i].f:-1);
      }
      return 0;
    }
    

      

  • 相关阅读:
    当简单的计算遇上了大数,其实大数运算也很简单
    揭开源码的神秘面纱,让源码从此无处藏身
    JAVA对象和XML文档、原来他们之间还有这一出
    JAVA反射其实就是那么一回事
    Metatable让我从心认知了Lua(相知篇)
    Github
    常见问题汇总
    文章目录
    前后端分离下使用SignalR
    IdentityServer_0_参考资料
  • 原文地址:https://www.cnblogs.com/clrs97/p/4679115.html
Copyright © 2011-2022 走看看