题面
题解
注意到题目没有给什么特殊的性质,除了直线随机生成。
所以考虑随机化算法或均摊算法。
有一种很神奇的分块做法:
考虑将整个平面分成 \(B\times B\) 块,每块大小 \(\dfrac{10^9}{B}\times\dfrac{10^9}{B}\),而且每一个块记录一下有哪些直线经过它,询问的时候直接枚举经过询问点所在块内的所有直线并判断统计。
分析一下时间复杂度:
首先是预处理,对于每一条直线,它经过的块数大约为 \(B\),所以这部分的时间复杂度是 \(O(nB)\)。
其次是询问时枚举当前块内的所有直线。刚刚我们得出了所有直线经过的块数为 \(O(nB)\) 级别的,那么每一块均摊下来经过直线条数约是:\(\dfrac{nB}{B^2}=\dfrac{n}{B}\),所以这部分的时间复杂度是 \(O(q\dfrac{n}{B})\)。
总时间复杂度 \(O(nB+q\dfrac{n}{B})\),取 \(B=\sqrt{n}\) 即可。
代码如下:
#include<bits/stdc++.h>
#define SN 350
#define N 100010
#define eps 1e-6
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
int n,q,x[N][2],y[N][2];
int block,len;
vector<int>v[SN][SN];
bool compare(double a,double b)
{
if(fabs(a-b)<eps) return 0;
return (a<b?-1:1);
}
int get(double x)
{
if(!compare(x,(int)x))
return ((int)x-1)/len+1;
return ((int)ceil(x)-1)/len+1;
}
int main()
{
n=read(),q=read();
block=sqrt(n);
len=1e9/block;
while(block*len<1e9) len++;
int check=1;
get(check);
for(int i=1;i<=n;i++)
{
x[i][0]=read(),y[i][0]=read(),x[i][1]=read(),y[i][1]=read();
if(x[i][0]==x[i][1])
{
int b=get(x[i][0]);
for(int j=1;j<=block;j++)
v[b][j].push_back(i);
}
else if(y[i][0]==y[i][1])
{
int b=get(y[i][0]);
for(int j=1;j<=block;j++)
v[j][b].push_back(i);
}
else
{
double k=1.0*(y[i][1]-y[i][0])/(x[i][1]-x[i][0]);
double b=1.0*y[i][0]-k*x[i][0];
double l=min(1e9,max(1.0,(1e9-b)/k)),r=max(1.0,min(1e9,(1-b)/k));
if(l>r) swap(l,r);
int xlb=get(l),xrb=get(r);
for(int j=xlb;j<=xrb;j++)
{
double xl=max(l,1.0*(j-1)*len+1),xr=min(r,1.0*j*len);
double yl=k*xl+b,yr=k*xr+b;
if(yl>yr) swap(yl,yr);
int ylb=get(yl),yrb=get(yr);
for(int k=ylb;k<=yrb;k++)
v[j][k].push_back(i);
}
}
}
while(q--)
{
int xx=read(),yy=read();
int xb=get(xx),yb=get(yy),ans=0;
for(int i=0,size=v[xb][yb].size();i<size;i++)
{
int k=v[xb][yb][i];
ans+=(1ll*(y[k][1]-y[k][0])*(xx-x[k][1])==1ll*(yy-y[k][1])*(x[k][1]-x[k][0]));
}
printf("%d\n",ans);
}
return 0;
}
标签:直线,ch,分块,int,dfrac,复杂度,XSY3904,nB
From: https://www.cnblogs.com/ez-lcw/p/16841167.html