zoukankan      html  css  js  c++  java
  • #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]);
    }
    
  • 相关阅读:
    LeetCode 面试题32
    LeetCode 102. 二叉树的层序遍历
    LeetCode 面试题32
    LeetCode 面试题32
    LeetCode 面试题31. 栈的压入、弹出序列
    LeetCode 946. 验证栈序列
    LeetCode 50. Pow(x, n)
    LeetCode 572. 另一个树的子树
    LeetCode 面试题50. 第一个只出现一次的字符
    LeetCode 面试题37. 序列化二叉树
  • 原文地址:https://www.cnblogs.com/gmh77/p/13500729.html
Copyright © 2011-2022 走看看