zoukankan      html  css  js  c++  java
  • HNOI2019 鱼 fish

    本来想写个改题记录的然后想了想改不完所以就分开写了= =

    https://www.luogu.org/problemnew/show/P5286

    显然枚举A,D,然后鱼头和鱼身分开来考虑。

    鱼身:先枚举B,C,那么BC的中点一定在线段AD(不包含端点)上,对于每一条直线维护一个vector存所有的点,将这个BC的中点插入进线段BC的垂直平分线的vector,然后对于一组AD,鱼身的方案数是vector上AD中间的点数,可以用upper_bound求。

    鱼尾:枚举D,对所有其他点极角排序,用双指针扫一遍所有点即可。具体难以描述请直接看代码

    这题细节巨多,考场上一看就会写,写了3h还没拍上以为暴力写挂走了,结果水到40分,如果没被卡常有60,然后今天又调了一个上午才过的= =说不定还有bug只是数据太水= =

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define il inline
    #define rg register
    #define vd void
    #define ll long long
    il int gi(){
        int x=0,f=0;char ch=getchar();
        while(!isdigit(ch))f^=ch=='-',ch=getchar();
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n;
    template<class T>il T gcd(T a,T b){return b?gcd(b,a%b):a;}
    struct number{
        ll x,y;
        number(){}
        number(const ll&a,const ll&b){
            ll g=gcd(llabs(a),llabs(b));
            x=a/g,y=b/g;
            if(y<0)x=-x,y=-y;
        }
    };
    il bool operator<(const number&a,const number&b){
        if(a.x^b.x)return a.x<b.x;
        return a.y<b.y;
    }
    il bool operator!=(const number&a,const number&b){return a.x!=b.x||a.y!=b.y;}
    struct line{number k,b;};
    il bool operator<(const line&a,const line&b){
        if(a.k!=b.k)return a.k<b.k;
        return a.b<b.b;
    }
    std::map<line,int>M;int cnt;
    int x[1010],y[1010];
    struct yyb{int i;double at2;}s[2010];
    il bool operator<(const yyb&a,const yyb&b){return a.at2<b.at2;}
    std::vector<int>vec[1000010];
    il ll getdist(int a,int b){
        return 1ll*(x[a]-x[b])*(x[a]-x[b])+1ll*(y[a]-y[b])*(y[a]-y[b]);
    }
    int tail[1010][1010];
    std::map<ll,int>mmp;
    int res,nowi;
    const double eps=1e-10,pi=acos(-1);
    il vd insert(int x){res+=mmp[getdist(nowi,x)]++;}
    il vd delet(int x){res-=--mmp[getdist(nowi,x)];}
    int main(){
        //freopen("fish.in","r",stdin);
        //freopen("fish.out","w",stdout);
        n=gi();
        for(int i=1;i<=n;++i)x[i]=gi(),y[i]=gi();
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j)
                if(y[i]==y[j]){
                    if(x[i]+x[j]&1)continue;
                    number k=(number){1,0},b=(number){(x[i]+x[j])/2,1};
                    if(M.find((line){k,b})==M.end())M[(line){k,b}]=++cnt;
                    vec[M[(line){k,b}]].push_back(y[i]*2);
                }else{
                    number k=(number){x[i]-x[j],y[j]-y[i]},b=(number){-1ll*(x[i]-x[j])*(x[i]+x[j])+1ll*(y[j]-y[i])*(y[j]+y[i]),2ll*(y[j]-y[i])};
                    if(M.find((line){k,b})==M.end())M[(line){k,b}]=++cnt;
                    vec[M[(line){k,b}]].push_back(x[i]==x[j]?x[i]*2:y[i]+y[j]);
                }
        for(int i=1;i<=n;++i){
            int m=0;
            for(int j=1;j<=n;++j)if(j!=i)s[++m]=(yyb){j,atan2(y[j]-y[i],x[j]-x[i])};
            std::sort(s+1,s+m+1);
            for(int i=1;i<=m;++i)s[i+m]=s[i],s[i+m].at2+=pi*2;
            mmp.clear();
            res=0;nowi=i;
            for(int j=1,p=0,q=0;j<=m;++j){
                while(s[p+1].at2+eps<s[j].at2+1.5*pi)insert(s[++p].i);
                while(s[q+1].at2<s[j].at2+0.5*pi+eps)delet(s[++q].i);
                tail[s[j].i][i]=res;
            }
        }
        for(int i=1;i<=cnt;++i)std::sort(vec[i].begin(),vec[i].end());
        ll ans=0;
        for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j){
                int xa=y[i],xb=y[j];
                if(xa==xb)xa=x[i],xb=x[j];
                if(xa>xb)std::swap(xa,xb);
                number k,b;
                if(x[i]==x[j])k=(number){1,0},b=(number){x[i],1};
                else k=(number){y[i]-y[j],x[i]-x[j]},b=(number){-1ll*x[i]*(y[i]-y[j])+1ll*y[i]*(x[i]-x[j]),x[i]-x[j]};
                if(M.find((line){k,b})==M.end())continue;
                int veci=M[(line){k,b}];
                ans+=(std::upper_bound(vec[veci].begin(),vec[veci].end(),xb*2-1)-std::upper_bound(vec[veci].begin(),vec[veci].end(),xa*2))*(tail[i][j]+tail[j][i]);
            }
        printf("%lld
    ",ans*4);
        return 0;
    }
    
  • 相关阅读:
    XJTUOJ13 (数论+FFT)
    ZOJ3956 ZJU2017校赛(dp)
    ZOJ3953 ZJU2017校赛(贪心)
    2014ACM/ICPC亚洲区西安站现场赛 F color(二项式反演)
    LOJ10129
    loj 10127最大数
    noip 选择客栈
    LOJ10121 与众不同
    CQOI 2006 简单题
    校门外的树
  • 原文地址:https://www.cnblogs.com/xzz_233/p/10669590.html
Copyright © 2011-2022 走看看