李超线段树维护线段!
找到覆盖的logn个区间,然后像直线一样去做就好了。
复杂度
O(nlog2n)
注意特殊处理不存在斜率的线段。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
#define mod 39989
#define mod1 1000000000
#define eps 1e-8
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n=40000,ans=0,m=0,c[40000];
inline int re(int x){return (x+ans-1)%mod+1;}
inline int re1(int x){return (x+ans-1)%mod1+1;}
struct Line{
int l,r;double k,b;
double f(int x){return k*x+b;}
}a[N];
struct node{
int x;
}tr[160010];
inline int sgn(double x){return (x>-eps)-(x<eps);}
inline int Max(int x,int y,int v){
if(!x) return y;
int ff=sgn(a[x].f(v)-a[y].f(v));
if(ff==1||ff==0&&x<y) return x;return y;
}
inline void ins(int p,int l,int r,int x,int y,int id){
if(x<=l&&r<=y){
if(!tr[p].x){tr[p].x=id;return;}
int fl=sgn(a[tr[p].x].f(l)-a[id].f(l)),fr=sgn(a[tr[p].x].f(r)-a[id].f(r));
if(fl>=0&&fr>=0) return;
if(fl==-1&&fr==-1){tr[p].x=id;return;}int mid=l+r>>1;
if(fl!=-1){
if(a[tr[p].x].f(mid)>a[id].f(mid)) ins(p<<1|1,mid+1,r,x,y,id);
else ins(p<<1,l,mid,x,y,tr[p].x),tr[p].x=id;
}else{
if(a[tr[p].x].f(mid)>a[id].f(mid)) ins(p<<1,l,mid,x,y,id);
else ins(p<<1|1,mid+1,r,x,y,tr[p].x),tr[p].x=id;
}return;
}int mid=l+r>>1;
if(x<=mid) ins(p<<1,l,mid,x,y,id);
if(y>mid) ins(p<<1|1,mid+1,r,x,y,id);
}
inline int ask(int p,int l,int r,int x){
if(l==r) return tr[p].x;
int mid=l+r>>1;
if(x<=mid) return Max(tr[p].x,ask(p<<1,l,mid,x),x);
return Max(tr[p].x,ask(p<<1|1,mid+1,r,x),x);
}
int main(){
// freopen("a.in","r",stdin);
int owo=read();
while(owo--){
int op=read();
if(op){
int x0=re(read()),y0=re1(read()),x1=re(read()),y1=re1(read());
a[++m].l=min(x0,x1);a[m].r=max(x0,x1);
if(x0==x1){a[m].k=0;a[m].b=max(y0,y1);c[x0]=Max(c[x0],m,x0);continue;}
a[m].k=(y1-y0)*1.0/(x1-x0),a[m].b=y0-a[m].k*x0;
ins(1,1,n,a[m].l,a[m].r,m);
}else{
int x=re(read());ans=ask(1,1,n,x);
ans=Max(c[x],ans,x);printf("%d\n",ans);
}
}return 0;
}