【模板】李超线段树 / [HEOI2013] Segment
在一些特殊的题目中,可以使用“标记永久化”代替标记的下传,但应用的局限性很大
- 在本题中,永久化的标记就是线段树所需要维护的信息,通过沿路比较得到单点查询的答案。在某个区间内,对于两条相交的线段,将其中更可能优的一条录入区间,将另外一条下传到其中一个子区间,就保证了log方的修改时间复杂度
#include <bits/stdc++.h>
using namespace std;
const int mod1=39989,mod2=1000000000;
struct seg
{
int x0,y0,x1,y1;
double calc(double x)
{
if(x0==x1)
{
return y1;
}
return y0+(x-x0)/(x1-x0)*(y1-y0);
}
}s[100005];
int tot;
struct t1
{
int l,r,v;
}t[200005];
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
t[p].v=0;
if(l==r)
{
return;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
}
const double eps=1e-9;
void change(int p,int l,int r,int x)
{
int mid=(t[p].l+t[p].r)>>1;
if(l<=t[p].l&&r>=t[p].r)
{
if(fabs(s[x].calc(mid)-s[t[p].v].calc(mid))<eps&&x>t[p].v)
{
swap(x,t[p].v);
}
else if(s[x].calc(mid)<s[t[p].v].calc(mid))
{
swap(x,t[p].v);
}
if(fabs(s[x].calc(t[p].r)-s[t[p].v].calc(t[p].r))<eps&&t[p].v<x)
{
change(p*2+1,l,r,t[p].v);
t[p].v=x;
}
else if(s[x].calc(t[p].r)<s[t[p].v].calc(t[p].r))
{
change(p*2+1,l,r,t[p].v);
t[p].v=x;
}
else if(fabs(s[x].calc(t[p].l)-s[t[p].v].calc(t[p].l))<eps&&t[p].v<x)
{
change(p*2,l,r,t[p].v);
t[p].v=x;
}
else if(s[x].calc(t[p].l)<s[t[p].v].calc(t[p].l))
{
change(p*2,l,r,t[p].v);
t[p].v=x;
}
else
{
t[p].v=x;
}
return;
}
if(l<=mid)
{
change(p*2,l,r,x);
}
if(r>mid)
{
change(p*2+1,l,r,x);
}
}
int ask(int p,int x)
{
if(t[p].l==t[p].r)
{
return t[p].v;
}
int mid=(t[p].l+t[p].r)>>1,va;
if(x<=mid)
{
va=ask(p*2,x);
}
else
{
va=ask(p*2+1,x);
}
if(fabs(s[t[p].v].calc(x)-s[va].calc(x))<eps)
{
return min(t[p].v,va);
}
else if(s[t[p].v].calc(x)>s[va].calc(x))
{
return t[p].v;
}
else
{
return va;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
s[0].x0=1;
s[0].x1=mod1;
s[0].y0=s[0].y1=0;
build(1,1,mod1);
int lastans=0;
for(int i=1;i<=n;i++)
{
int opt;
cin>>opt;
if(opt==0)
{
int k;
cin>>k;
lastans=ask(1,(k+lastans-1)%mod1+1);
cout<<lastans<<"\n";
}
else
{
tot++;
cin>>s[tot].x0>>s[tot].y0>>s[tot].x1>>s[tot].y1;
s[tot].x0=(s[tot].x0+lastans-1)%mod1+1;
s[tot].y0=(s[tot].y0+lastans-1)%mod2+1;
s[tot].x1=(s[tot].x1+lastans-1)%mod1+1;
s[tot].y1=(s[tot].y1+lastans-1)%mod2+1;
if(s[tot].x0>s[tot].x1)
{
swap(s[tot].x0,s[tot].x1);
swap(s[tot].y0,s[tot].y1);
}
change(1,s[tot].x0,s[tot].x1,tot);
}
}
return 0;
}

浙公网安备 33010602011771号