P4097 [HEOI2013]Segment

李超线段树入门。

#include<iostream>
#include<cstdio>
#include<cmath>
#define R register int
#define ll long long
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
  register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
  do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} const int N=40000,M=100010,X=39989,Y=1e9;
const double eps=1e-8;
int n,id,ans=-1;
double k[M],b[M];
int s[(N+10)<<2];
#define ls (tr<<1)
#define rs (tr<<1|1)
inline int dcmp(const double& x) {
  return !fabs(x)<=eps;
}
inline double f(int i,int x) {return k[i]*x+b[i];}
inline bool ck(int i,int j,int x) {
  double fi=f(i,x),fj=f(j,x);
  return dcmp(fi-fj)?fi<fj:j<i;
}
inline void change(int tr,int l,int r,int LL,int RR,int p) {
  if(LL<=l&&r<=RR) {
    if(ck(p,s[tr],l)&&ck(p,s[tr],r)) return ;//没有之前的优
    if(ck(s[tr],p,l)&&ck(s[tr],p,r)) {
      s[tr]=p; return ;//完全比之前的优
    }
    R md=(l+r)>>1;
    if(ck(s[tr],p,md)) swap(s[tr],p);//保证中点最优
    if(ck(s[tr],p,l)) change(ls,l,md,LL,RR,p);//向下递归
    else change(rs,md+1,r,LL,RR,p);
    return ;
  } R md=(l+r)>>1;
  if(LL<=md) change(ls,l,md,LL,RR,p);
  if(RR>md) change(rs,md+1,r,LL,RR,p);
}
inline int query(int tr,int l,int r,int p) {
  if(l==r) return s[tr]; R md=(l+r)>>1,t;
  return ck(s[tr],t=(p<=md?query(ls,l,md,p):query(rs,md+1,r,p)),p)?t:s[tr];
}
inline void main() {
  n=g();
  for(R i=1,op,x0,y0,x1,y1;i<=n;++i) {
    op=g();
    if(op) {
      x0=(g()+ans+X)%X+1,y0=((ll)g()+ans+Y)%Y+1,
      x1=(g()+ans+X)%X+1,y1=((ll)g()+ans+Y)%Y+1;
      ++id; if(x0>x1) swap(x0,x1),swap(y0,y1);
      if(x0==x1) k[id]=0,b[id]=max(y0,y1);
      else k[id]=1.0*(y1-y0)/(x1-x0),b[id]=y0-k[id]*x0;
      change(1,1,N,x0,x1,id);
    } else {
      x0=(g()+ans+X)%X+1;
      printf("%d\n",ans=query(1,1,N,x0));
      --ans;
    }
  }
}
} signed main() {Luitaryi::main(); return 0;}

2020.01.16

posted @ 2020-01-17 21:41  LuitaryiJack  阅读(166)  评论(0编辑  收藏  举报