zoukankan      html  css  js  c++  java
  • 【BZOJ 3165】 [Heoi2013]Segment 李超线段树

    所谓李超线段树就是解决此题一类的问题(线段覆盖查询点最大(小)),把原本计算几何的题目变成了简单的线段树,巧妙地结合了线段树的标记永久化与标记下传,在不考虑精度误差的影响下,打法应该是这样的。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define mid(a,b) ((a+b)>>1)
    typedef long double ld;
    const int Inf_x=39989;
    const int Inf_y=1000000000;
    int cnt,sz;
    struct Line{
      ld k,b;int id;
      inline ld f(int x){return k*x+b;}
      inline ld point(Line a){return (b-a.b)/(a.k-k);}
    };
    struct lcSegment_Tree{
      lcSegment_Tree *ch[2];
      Line line;
    }seg[Inf_x<<4],*root;
    void pushdown(lcSegment_Tree *p,int l,int r,Line line){
      ld a1=p->line.f(l),a2=line.f(l),b1=p->line.f(r),b2=line.f(r);
      if(a1<=a2&&b1<=b2){p->line=line;return;}
      if(a1>a2&&b1>b2)return;
      ld x=line.point(p->line);
      if(x<=mid(l,r)){
        if(a1>a2)pushdown(p->ch[0],l,mid(l,r),p->line),p->line=line;
        else pushdown(p->ch[0],l,mid(l,r),line);
      }else{
        if(a1>a2)pushdown(p->ch[1],mid(l,r)+1,r,line);
        else pushdown(p->ch[1],mid(l,r)+1,r,p->line),p->line=line;
      }
    }
    void build(lcSegment_Tree *&p,int l,int r){
      p=seg+sz,++sz;
      if(l==r)return;
      build(p->ch[0],l,mid(l,r));
      build(p->ch[1],mid(l,r)+1,r);
    }
    void insert(lcSegment_Tree *p,int l,int r,int z,int y,Line line){
      if(z<=l&&r<=y){pushdown(p,l,r,line);return;}
      if(z<=mid(l,r))insert(p->ch[0],l,mid(l,r),z,y,line);
      if(mid(l,r)<y)insert(p->ch[1],mid(l,r)+1,r,z,y,line);
    }
    void query(lcSegment_Tree *p,int l,int r,int pos,ld last,int &ans){
      if(p->line.f(pos)>last||(p->line.f(pos)==last&&p->line.id<ans))ans=p->line.id,last=p->line.f(pos);
      if(l==r)return;
      if(pos<=mid(l,r))query(p->ch[0],l,mid(l,r),pos,last,ans);
      else query(p->ch[1],mid(l,r)+1,r,pos,last,ans);
    }
    int main(){
      int T,opt,zzh1,zzh2,wq1,wq2,lastans=0,x;Line temp;
      scanf("%d",&T),build(root,1,Inf_x);
      while(T--){
        scanf("%d",&opt);
        if(opt){
          scanf("%d%d%d%d",&zzh1,&zzh2,&wq1,&wq2);
          zzh1=(zzh1+lastans-1)%Inf_x+1,zzh2=(zzh2+lastans-1)%Inf_y+1,
          wq1=(wq1+lastans-1)%Inf_x+1,wq2=(wq2+lastans-1)%Inf_y+1;
          if(wq1>zzh1)wq1^=zzh1^=wq1^=zzh1,wq2^=zzh2^=wq2^=zzh2;
          if(wq1==zzh1)temp.k=0.,temp.b=std::max(wq2,zzh2);
          else temp.k=(ld)(zzh2-wq2)/(zzh1-wq1),temp.b=zzh2-temp.k*zzh1;
          temp.id=++cnt,insert(root,1,Inf_x,wq1,zzh1,temp);
        }else{
          scanf("%d",&x),x=(x+lastans-1)%Inf_x+1,lastans=0;
          query(root,1,Inf_x,x,0.,lastans);
          printf("%d
    ",lastans);
        }
      }return 0;
    }
  • 相关阅读:
    HTML5基础知识(1)--上标和下标文本
    jQuery基础--样式篇(5)
    jQuery基础--样式篇(4)
    jQuery基础--样式篇(3)
    jQuery基础--样式篇(2)
    jQuery基础--样式篇(1)
    使用D3绘制图表(7)--饼状图
    使用D3绘制图表(6)--竖直柱状图表
    安装Centos 7 错误解决
    linux下搭建LAMP
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7601879.html
Copyright © 2011-2022 走看看