题意
有两种操作
1.插入一个每条边与坐标轴平行的矩形()
2.从原点射出一个光,问他最先碰到那个矩形
(所有点都在x轴正半轴或y轴正半轴或第一象限中)
题解
离线处理啦
我们通过极坐标排序,我们可以离散化,每个矩形我们就可以看做是覆盖了一段极角坐标
显然我们可以把一个矩形简化成左边和下边那两条线段
然后我们可以用两棵线段树来维护线段(真·线段树)
我们分开处理横的和纵的
然后分别更新啦,可以由于标记不会删除,可以标记永久化
然后我们都取对应的横/纵坐标最小的,然后取标号更大的
注意关于查询x轴上y轴上的特判!
略恶心…
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define lch x<<1
#define rch x<<1|1
#define EPS 1e-10
using namespace std;
typedef long long ll;
const int N=1000005,M=4000005;
int dcmp(double x){
if(fabs(x)<EPS)
return 0;
return x>0?1:-1;
}
double p[N];
int op[N];
int p1[N],p2[N],p3[N];
double p11[N],p21[N],p31[N];
int t1[N],t2[N];
int l[N],r[N],q[N];
int x[N],y[N];
double q1[N];
int a1[M*4],a2[M*4];
int b1[M*4],b2[M*4];
//!chuizhi
int n;
void Modify(int *a,int *b,int x,int l,int r,int pl,int pr,int i,int z){
if(pl<=l&&r<=pr){
if(b[x]==0||b[x]>=z){
b[x]=z;
a[x]=i;
}
return ;
}
if(b[x]!=0&&b[x]<z){
return ;
}
int mid=(l+r)>>1;
if(pl<=mid)
Modify(a,b,lch,l,mid,pl,pr,i,z);
if(pr>mid)
Modify(a,b,rch,mid+1,r,pl,pr,i,z);
}
void Modify(int i){
Modify(a1,b1,1,1,n,p1[i],p2[i],i,t1[i]);
Modify(a2,b2,1,1,n,p2[i],p3[i],i,t2[i]);
}
int Query(int *a,int *b,int x,int l,int r,int p){
if(l==r)
return x;
int mid=(l+r)>>1;
if(a[x]){
if(b[lch]==0||b[lch]>b[x]||(b[lch]==b[x]&&a[lch]<a[x])){
b[lch]=b[x];
a[lch]=a[x];
}
if(b[rch]==0||b[rch]>b[x]||(b[rch]==b[x]&&a[rch]<a[x])){
b[rch]=b[x];
a[rch]=a[x];
}
}
if(p<=mid)
return Query(a,b,lch,l,mid,p);
else
return Query(a,b,rch,mid+1,r,p);
}
int Query(int i){
int r1=Query(a1,b1,1,1,n,q[i]);
int r2=Query(a2,b2,1,1,n,q[i]);
if(!a1[r1]||x[i]==0)
return a2[r2];
if(!a2[r2]||y[i]==0)
return a1[r1];
double z=1.0*b2[r2]*x[i]/y[i];
if(z>b1[r1])
return a1[r1];
else if(z<b1[r1])
return a2[r2];
else
return max(a1[r1],a2[r2]);
}
int main()
{
int cnt=0;
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&op[i]);
double l,r,s,t;
if(op[i]==1){
scanf("%lf%lf%lf%lf",&l,&s,&r,&t);
t1[i]=l,t2[i]=s;
p11[i]=-1.0*t/l;//取-只是为了从大到小..
p21[i]=-1.0*s/l;
p31[i]=-1.0*s/r;
p[++cnt]=p11[i];
p[++cnt]=p21[i];
p[++cnt]=p31[i];
}
else{
scanf("%d%d",&x[i],&y[i]);
q1[i]=-1.0*y[i]/x[i];
p[++cnt]=q1[i];
}
}
sort(p+1,p+cnt+1);
n=unique(p+1,p+cnt+1)-p-1;
for(int i=1;i<=m;i++)
if(op[i]==1){
p1[i]=lower_bound(p+1,p+n+1,p11[i])-p;
p2[i]=lower_bound(p+1,p+n+1,p21[i])-p;
p3[i]=lower_bound(p+1,p+n+1,p31[i])-p;
}
else
q[i]=lower_bound(p+1,p+n+1,q1[i])-p;
for(int i=1;i<=m;i++)
if(op[i]==1)
Modify(i);
else{
int ans=Query(i);
printf("%d\n",ans);
}
}