比赛 26暑假集训模拟赛1 评测结果 AAAAAAAAAA
题目名称 光线追踪 最终得分 100
用户昵称 运行时间 1.207 s
代码语言 C++ 内存使用 11.22 MiB
提交时间 2026-06-29 12:25:34
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INT_MAX (int)(2e9)
#define pr pair<int,int>
 
const int N=3e5+10;
 
int n,q;
 
struct Query{
    int op;
    int x0,y0,x1,y1;
}Q[N];
 
pr li[N];
 
inline int read(){
    int t=0,f=1;
    register char c=getchar();
    while(c<'0'||c>'9') f=(c=='-')?(-1):(f),c=getchar();
    while(c>='0'&&c<='9') t=(t<<3)+(t<<1)+(c^48),c=getchar();
    return t*f;
}
 
void qmin(pr &x,pr y){
    if(x.first>y.first) x=y;
    else if(x.first==y.first&&x.second<y.second) x=y;
}
 
struct Tree{
    #define mid (l+r>>1)
    
    pr tr[N<<2];
    
    void build(int p,int l,int r){
        tr[p]={INT_MAX,0};
        if(l==r) return;
        build(p<<1,l,mid),build(p<<1|1,mid+1,r); 
    }
    
    void update(int p,int l,int r,int L,int R,pr x){
        if(L<=l&&R>=r) return qmin(tr[p],x);
        if(L<=mid) update(p<<1,l,mid,L,R,x);
        if(R>mid) update(p<<1|1,mid+1,r,L,R,x);
    }
    
    void query(int p,int l,int r,int x,pr &res){
        qmin(res,tr[p]);
        if(l==r) return;
        if(x<=mid) query(p<<1,l,mid,x,res);
        else query(p<<1|1,mid+1,r,x,res);
    }
    
    #undef mid
}Tr1,Tr2;
//Tr1 use x to sort
//Tr2 use y to sort
 
bool cmp(pr x,pr y){
    return x.first*y.second<x.second*y.first;
}
 
int sc(pr x){
    int l=1,r=n,mid,ans=0;
    while(l<=r){
        mid=l+r>>1;
        if(cmp(li[mid],x)) l=mid+1;
        else ans=mid,r=mid-1;
    }
    return ans;
}
 
signed main(){
    freopen("raytracing.in","r",stdin);
    freopen("raytracing.out","w",stdout);
    q=read();
    for(int i=1;i<=q;i++){
        Q[i].op=read();
        if(Q[i].op==1){
            Q[i].x0=read(),Q[i].y0=read(),Q[i].x1=read(),Q[i].y1=read();
            li[++n]={Q[i].y0,Q[i].x0},li[++n]={Q[i].y1,Q[i].x0},li[++n]={Q[i].y0,Q[i].x1};
        }else{
            Q[i].x0=read(),Q[i].y0=read();
            li[++n]={Q[i].y0,Q[i].x0};
        }
    }
    for(int i=1;i<=n;i++){
        if(li[i].first==0) li[i].second=1;
        else if(li[i].second==0) li[i].first=1;
        else{
            int gcd=__gcd(li[i].first,li[i].second);
            li[i].first/=gcd,li[i].second/=gcd;
        }
    }
    sort(li+1,li+1+n,cmp);
    n=unique(li+1,li+1+n)-(li+1);
    Tr1.build(1,1,n),Tr2.build(1,1,n);
    for(int i=1;i<=q;i++){
        if(Q[i].op==1){
            int l=sc({Q[i].y0,Q[i].x1}),mid=sc({Q[i].y0,Q[i].x0}),r=sc({Q[i].y1,Q[i].x0});
            Tr2.update(1,1,n,l,mid,{Q[i].y0,i}),Tr1.update(1,1,n,mid,r,{Q[i].x0,i});
        }else{
            int x=sc({Q[i].y0,Q[i].x0});
            pr ansx={INT_MAX,0},ansy={INT_MAX,0};
            Tr1.query(1,1,n,x,ansx),Tr2.query(1,1,n,x,ansy);
            if(Q[i].y0==0) cout<<ansx.second<<"\n";
            else if(Q[i].x0==0) cout<<ansy.second<<"\n";
            else if(cmp({ansy.first,ansx.first},li[x])) cout<<ansy.second<<"\n";
            else if(cmp(li[x],{ansy.first,ansx.first})) cout<<ansx.second<<"\n";
            else cout<<max(ansy.second,ansx.second)<<"\n";
        }
    }
    return 0;
}