ZOJ3379 Master Spark

(¦3[____]←  扫描线问题,抛物线方程为 y=a*x*x 形式,

对每个点求出抛物线中轴的范围theta-delta~theta+delta,

theta = atan2(y,x),delta则用方程组可解x*x+y*y=z*z+(a*z*z)^2,tan(theta)=z/(a*z*z),故theta = atan2(1,a*z)

然后从-PI到PI进行扫描,用最小堆维护即可

这题调了好久啊,把>写成<,把double写成int。。。= =、捉鸡

#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<utility>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=30010;
const double TPI = 2*acos(-1);

double x[N],y[N];
vector<pair<double,double> > ang;

int cnt;
double heap[N];

void heap_add(double a)
{
    heap[++cnt]=a;
    int u,ch=cnt;
    double t=heap[cnt];
    u = cnt>>1;
    while(u&&heap[u]>t) {
        heap[ch]=heap[u];
        ch>>=1;
        u=ch>>1;
    }
    heap[ch]=t;
}

void heap_pop()
{
    heap[1]=heap[cnt];
    --cnt;
    int u=1,chl,chr,ch;
    double t=heap[1];
    while(cnt) {
        chl=u<<1;
        chr=chl|1;
        if(chr<=cnt&&heap[chl]<heap[chr]) ch=chl;
        else if(chr<=cnt&&heap[chl]>heap[chr]) ch=chr;
        else if(chl<=cnt) ch=chl;
        else {
            heap[u]=t;
            break;
        }
        if(t>heap[ch]) {
            heap[u]=heap[ch];
            u=ch;
        }
        else {
            heap[u]=t;
            break;
        }
    }
}

int main()
{
    int n,ans;
    double a,theta,delta,z;
    while(scanf("%d%lf",&n,&a)==2) {
        ang.clear();
        cnt = 0;
        for(int i=0;i<n;++i)
            scanf("%lf",x+i);
        for(int i=0;i<n;++i)
            scanf("%lf",y+i);

        for(int i=0;i<n;++i) {
            theta=atan2(y[i],x[i]);
            z=sqrt((sqrt(1+4*a*a*(x[i]*x[i]+y[i]*y[i]))-1)/(2*a*a));
            delta = atan2(1,a*z);
            ang.push_back(make_pair(remainder(theta-delta,TPI),remainder(theta+delta,TPI)));
            if(ang.back().first>ang.back().second) {
                heap_add(ang.back().second);
                ang.back().second+=TPI;
            }
        }

        ans = cnt;
        sort(ang.begin(),ang.end());
        for(vector<pair<double,double> >::iterator it=ang.begin();it!=ang.end();++it) {
            heap_add(it->second);
            while(cnt&&heap[1] < it->first) {
                heap_pop();
            }
            ans=max(ans,cnt);
        }
        printf("%d daze\n",ans);
    }
}

 

posted @ 2014-07-15 13:40  MoriMiya  Views(263)  Comments(0Edit  收藏  举报