#553. 【UNR #4】己酸集合

题目描述


题解

考场写了35,本机跑5s感觉布星就没调,结果因为把long long存到double里面爆精度WA掉了,实际跑了2s,然后套个平衡规划就过了

把询问离线,两个点到询问点距离的关系只会改变一次,连线做中垂线交y轴即可得到改变的位置,堆维护即可有35,分成10块搞即可AC

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define abs(x) ((x)>0?(x):-(x))
#define sqr(x) ((x)*(x))
#define ll long long
//#define file
using namespace std;

struct type{ll x,y;int id;} a[12002],b[1000001];
struct Type{double s;int x,y;} s;
priority_queue<Type> hp;
int ans[1000001],c[12001],n,Q,i,j,k,l,r,mid,I,l1,r1,S;
char st[21],ch;
ll R;

bool operator < (Type a,Type b) {return a.s>b.s;}
int Read() {int x=0,k=1;ch=getchar(); while (ch<'0' || ch>'9') k=(ch=='-')?-1:k,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return k*x;}
void Write(int x) {if (!x) {putchar('0');putchar('
');return;}int i=0; while (x) st[++i]=x%10+'0',x/=10; while (i) putchar(st[i--]);putchar('
');}
bool cmp(type a,type b) {return a.y<b.y || a.y==b.y && a.x<b.x;}
void swap(int &x,int &y) {int z=x;x=y;y=z;}
double js(int i,int j) {if (a[i].y==a[j].y) return 2133333333; return ((double)sqr(a[i].x)+sqr(a[i].y)-sqr(a[j].x)-sqr(a[j].y))/(2*(a[i].y-a[j].y));}
void add(int i,int j) {double s;if (a[i].y!=a[j].y) {s=js(i,j);hp.push({s,a[i].id,a[j].id});};}

int main()
{
	#ifdef file
	freopen("circle.in","r",stdin);
	freopen("circle.out","w",stdout);
	#endif
	
	n=Read();Q=Read();
	fo(i,1,n) a[i].x=Read(),a[i].y=Read(),a[i].x=abs(a[i].x);
	fo(i,1,Q) b[i].y=Read(),b[i].x=Read(),b[i].id=i;
	sort(a+1,a+n+1,cmp);
	sort(b+1,b+Q+1,cmp);
	fo(i,1,n) a[i].id=i,c[i]=i;
	
	S=10;
	fo(I,1,S)
	{
		l1=(I-1)*(n/S)+1;r1=I*(n/S);
		if (I==S) r1=n;
		
		fo(i,l1,r1-1) if (a[i].y<a[i+1].y) add(i,i+1);
		fo(i,1,Q)
		{
			while (!hp.empty())
			{
				s=hp.top();
				if (s.s-0.00000001>b[i].y) break;
				hp.pop();
				
				if (a[c[s.x]+1].id==s.y)
				{
					j=c[s.x];
					a[0]=a[j],a[j]=a[j+1],a[j+1]=a[0];
					++c[s.x],--c[s.y];
					if (j>l1 && a[j-1].y<a[j].y) add(j-1,j);
					if (j+1<r1 && a[j+1].y<a[j+2].y) add(j+1,j+2);
				}
			}
			
			R=sqr(b[i].x);
			l=l1;r=r1;
			while (l<r)
			{
				mid=(l+r)/2;
				if (sqr(a[mid].x)+sqr(a[mid].y-b[i].y)<=R)
				l=mid+1; else r=mid;
			}
			l-=(sqr(a[l].x)+sqr(a[l].y-b[i].y)>R);
			
			ans[b[i].id]+=l-l1+1;
		}
		if (I<S) while (!hp.empty()) hp.pop();
	}
	
	fo(i,1,Q) Write(ans[i]);
}
原文地址:https://www.cnblogs.com/gmh77/p/13500729.html