传送门

这题真的牛皮,还好考场没去刚(

这题口胡起来真的简单

首先枚举D点,然后对其他所有点按极角排序,同时记录到D的距离.然后按照极角序枚举A,那么鱼尾的两个点的极角范围就是A关于D对称的那个向量,然后左右各\(\frac{\pi}{2}\),因为A的极角增大,区间也会往后移,然后问题就是一个范围内同距离点对数,学过莫队的都会吧(逃

然后处理BC,一对合法的BC,首先要和AD垂直,然后BC中点要落在线段AD(不含端点)上,那么,BC中垂线必须唯一(中垂线的斜率和截距唯一),并且BC对应的中点的坐标范围要夹在A和D之间,然后预处理所有线段,按中垂线斜率,截距以及中点的x,y坐标之和三维度排序,每次有个AD,就能直接二分找到合法区间,然后直接算数量

注意BC,EF之间可以反过来,所以最后答案*4

代码仅供参考

// luogu-judger-enable-o2
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db long double using namespace std;
const int N=1000+10;
const db eps=1e-13,pi=acos(-1);
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
struct point
{
db x,y;
point(){}
point(db nx,db ny){x=nx,y=ny;}
point operator - (const point &bb) const {return point(x-bb.x,y-bb.y);}
db operator * (const point &bb) const {return x*bb.x+y*bb.y;}
db operator ^(const point &bb) const {return x*bb.y-y*bb.x;}
}a[N],b[N],fk;
db sq(db x){return x*x;}
db dis(point aa,point bb){return sqrt(sq(aa.x-bb.x)+sq(aa.y-bb.y));}
db ang(point aa,point bb){return atan2(bb.y-aa.y,bb.x-aa.x);}
int n,m,bk[N];
LL ans,sb[N],tb,tc,na;
struct node
{
db dx,dy,b,x;
bool operator < (const node &bb) const
{
if(fabs(dy*bb.dx-dx*bb.dy)>eps) return dy*bb.dx<dx*bb.dy;
if(!dx&&fabs(b-bb.b)>eps) return b<bb.b;
else if(fabs(b*bb.dx-bb.b*dx)>eps) return b*bb.dx<bb.b*dx;
return x<bb.x;
}
}p2[N*N];
struct nn
{
db a,x,y;LL d;
bool operator < (const nn &bb) const {return a<bb.a;}
}vc[N<<1]; int main()
{
n=rd();
for(int i=1;i<=n;++i)
{
int x=rd(),y=rd();
a[i]=point(x,y);
}
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
{
db dx=-(a[i].y-a[j].y),dy=a[i].x-a[j].x,k=-(a[i].x-a[j].x+(fabs(a[i].x-a[j].x)<eps?eps:0))/(a[i].y-a[j].y+(fabs(a[i].y-a[j].y)<eps?eps:0));
if(dx<0) dx=-dx,dy=-dy;
if(fabs(dx)<eps) dy=1;
db mx=(a[i].x+a[j].x)/2,my=(a[i].y+a[j].y)/2,bb=dx*my-dy*mx;
p2[++m]=(node){dx,dy,dx?bb:mx,fabs(k+1)>eps?mx+my:mx};
}
sort(p2+1,p2+m+1);
p2[41]<p2[42];
for(int i=1;i<=n;++i)
{
memset(bk,0,sizeof(bk)),na=tb=tc=0;
for(int j=1;j<=n;++j)
if(i!=j)
{
LL sx=floor(a[i].x+0.5),sy=floor(a[i].y+0.5),tx=floor(a[j].x+0.5),ty=floor(a[j].y+0.5);
vc[++tc]=(nn){ang(a[i],a[j]),a[j].x,a[j].y,(sx-tx)*(sx-tx)+(sy-ty)*(sy-ty)};
sb[++tb]=(sx-tx)*(sx-tx)+(sy-ty)*(sy-ty);
}
sort(vc+1,vc+tc+1);
sort(sb+1,sb+tb+1),tb=unique(sb+1,sb+tb+1)-sb-1;
for(int j=1;j<=tc;++j) vc[j].d=lower_bound(sb+1,sb+tb+1,vc[j].d)-sb;
for(int j=1;j<=tc;++j) vc[j+tc]=vc[j],vc[j+tc].a+=pi+pi;
for(int j=1,l=1,r=0;j<=tc;++j)
{
while(r<tc+tc&&vc[r+1].a<vc[j].a+1.5*pi-eps) ++r,++bk[vc[r].d],na+=bk[vc[r].d]-1;
while(vc[l].a<vc[j].a+0.5*pi+eps) na-=bk[vc[l].d]-1,--bk[vc[l].d],++l;
db dx=a[i].x-vc[j].x,dy=a[i].y-vc[j].y,k=(a[i].y-vc[j].y+(fabs(a[i].y-vc[j].y)<eps?eps:0))/(a[i].x-vc[j].x+(fabs(a[i].x-vc[j].x)<eps?eps:0));
if(dx<0) dx=-dx,dy=-dy;
if(fabs(dx)<eps) dy=1;
db bb=a[i].y*dx-a[i].x*dy,ll=fabs(k+1)>eps?a[i].x+a[i].y:a[i].x,rr=fabs(k+1)>eps?vc[j].x+vc[j].y:vc[j].x;
if(ll>rr) swap(ll,rr);
int sl=upper_bound(p2+1,p2+m+1,(node){dx,dy,dx?bb:a[i].x,ll+eps})-p2,sr=lower_bound(p2+1,p2+m+1,(node){dx,dy,dx?bb:a[i].x,rr-eps})-p2-1;
ans+=na*(sr-sl+1);
}
}
printf("%lld\n",ans<<2);
//awsl
return 0;
}

luogu P5286 [HNOI2019]鱼的更多相关文章

  1. HNOI2019 鱼 fish

    本来想写个改题记录的然后想了想改不完所以就分开写了= = https://www.luogu.org/problemnew/show/P5286 显然枚举A,D,然后鱼头和鱼身分开来考虑. 鱼身:先枚 ...

  2. [HNOI2019]鱼

    Luogu5286 \(2019.4.14\),新生第一题,改了\(3\)个小时 题解-租酥雨,和出题人给的正解一模一样 枚举\(AD\),分别考虑鱼身\(BC\)和鱼尾\(EF\) 到\(E\),\ ...

  3. [HNOI2019]鱼(计算几何)

    看到数据范围n<=1000,但感觉用O(n^2)不现实,所以考虑方向应该是O(n^2logn). 一种暴力做法:用vector存到1点相同的2点和到2点相同的1点,然后枚举A,枚举BC,再枚举D ...

  4. Luogu P5292 [HNOI2019]校园旅行

    非常妙的一道思博题啊,不愧是myy出的题 首先我们考虑一个暴力DP,直接开一个数组\(f_{i,j}\)表示\(i\to j\)的路径能否构成回文串 考虑直接拿一个队列来转移,队列里存的都是\(f_{ ...

  5. luogu P5287 [HNOI2019]JOJO

    传送门 神™这题暴力能A,这出题人都没造那种我考场就想到的数据,难怪我的垃圾做法有分 先考虑没有撤销操作怎么做,因为每次插入一段一样的字符,所以我们可以把\(x\)个字符\(c\)定义为\(cx\), ...

  6. luogu P5288 [HNOI2019]多边形

    传送门 这是什么神仙操作... 首先要注意一些性质.首先每一个\((x,n)\)的边可以把当前多边形分成两半,这两半的操作是独立的.然后对于某一个没有\((x,n)\)的边的多边形,最优操作是唯一的. ...

  7. luogu P5293 [HNOI2019]白兔之舞

    传送门 关于这题答案,因为在所有行,往后跳到任意一行的\(w_{i,j}\)都是一样的,所以可以算出跳\(x\)步的答案然后乘上\(\binom{l}{x}\),也就是枚举跳到了哪些行 如果记跳x步的 ...

  8. luogu P5294 [HNOI2019]序列

    传送门 这个什么鬼证明直接看uoj的题解吧根本不会证明 首先方案一定是若干段等值的\(B\),然后对于一段,\(B\)的值应该是\(A\)的平均值.这个最优方案是可以线性构造的,也就是维护以区间平均值 ...

  9. 【洛谷5286】[HNOI2019] 鱼(计算几何)

    点此看题面 大致题意: 给你\(n\)个点,让你求鱼形图的数量. 核心思路 首先,考虑到\(n\)这么小,我们可以枚举线段\(AD\),再去找符合条件的\(BC,EF\). 然后,不难发现\(BC\) ...

随机推荐

  1. Cursor: Pin S Wait On X In The Top 5 Wait Events

    Wait Events , Posted in: Technical Track Tags: Group Blog Posts, Oracle, Technical Blog Lately, wait ...

  2. 深入理解 path-to-regexp.js 及源码分析

    阅读目录 一:path-to-regexp.js 源码分析如下: 二:pathToRegexp 的方法使用 回到顶部 一:path-to-regexp.js 源码分析如下: 我们在vue-router ...

  3. Linux soft lockup分析

    关键词:watchdog.soft lockup.percpu thread.lockdep等. 近日遇到一个soft lockup问题,打印类似“[ 56.032356] NMI watchdog: ...

  4. 【转】详解springboot-修改内置tomcat版本

    1.解析Spring Boot父级依赖 <parent> <groupId>org.springframework.boot</groupId> <artif ...

  5. jquery.filter() 实现元素前3个显示,其余的隐藏

    <head> <meta charset="UTF-8"> <title></title> <style>   li { ...

  6. React Native之支付集成(微信 支付宝)(ios android)

    React Native之支付集成(微信 支付宝)(ios android) 一,需求分析 1.1,app在线充值与提现 二,技术介绍与集成 2.1,微信支付 2.1.1,Android配置 详细配置 ...

  7. 【翻译】IdentityServer4:基于资源的配置

    这篇文章基于https://leastprivilege.com/2016/12/01/new-in-identityserver4-resource-based-configuration/进行翻译 ...

  8. 输入输出流ObjectInputStream、ObjectOutputStream(对象序列化与反序列化)

    对象的输入输出流 : 主要的作用是用于写入对象信息与读取对象信息. 对象信息一旦写到文件上那么对象的信息就可以做到持久化了 对象的输出流: ObjectOutputStream 对象的输入流:  Ob ...

  9. git 回退各种场景操作

    在git的一般使用中,如果发现错误的将不想提交的文件add进入index之后,想回退取消,则可以使用命令:git reset HEAD <file>...,同时git add完毕之后,gi ...

  10. java并发编程实践——王宝令(极客时间)学习笔记

    1.并发 分工:如何高效地拆解任务并分配给线程 同步:线程之间如何协作 互斥:保证同一时刻只允许一个线程访问共享资源 Fork/Join 框架就是一种分工模式,CountDownLatch 就是一种典 ...