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

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只是数据太水= =

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define il inline
  4. #define rg register
  5. #define vd void
  6. #define ll long long
  7. il int gi(){
  8. int x=0,f=0;char ch=getchar();
  9. while(!isdigit(ch))f^=ch=='-',ch=getchar();
  10. while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
  11. return f?-x:x;
  12. }
  13. int n;
  14. template<class T>il T gcd(T a,T b){return b?gcd(b,a%b):a;}
  15. struct number{
  16. ll x,y;
  17. number(){}
  18. number(const ll&a,const ll&b){
  19. ll g=gcd(llabs(a),llabs(b));
  20. x=a/g,y=b/g;
  21. if(y<0)x=-x,y=-y;
  22. }
  23. };
  24. il bool operator<(const number&a,const number&b){
  25. if(a.x^b.x)return a.x<b.x;
  26. return a.y<b.y;
  27. }
  28. il bool operator!=(const number&a,const number&b){return a.x!=b.x||a.y!=b.y;}
  29. struct line{number k,b;};
  30. il bool operator<(const line&a,const line&b){
  31. if(a.k!=b.k)return a.k<b.k;
  32. return a.b<b.b;
  33. }
  34. std::map<line,int>M;int cnt;
  35. int x[1010],y[1010];
  36. struct yyb{int i;double at2;}s[2010];
  37. il bool operator<(const yyb&a,const yyb&b){return a.at2<b.at2;}
  38. std::vector<int>vec[1000010];
  39. il ll getdist(int a,int b){
  40. return 1ll*(x[a]-x[b])*(x[a]-x[b])+1ll*(y[a]-y[b])*(y[a]-y[b]);
  41. }
  42. int tail[1010][1010];
  43. std::map<ll,int>mmp;
  44. int res,nowi;
  45. const double eps=1e-10,pi=acos(-1);
  46. il vd insert(int x){res+=mmp[getdist(nowi,x)]++;}
  47. il vd delet(int x){res-=--mmp[getdist(nowi,x)];}
  48. int main(){
  49. //freopen("fish.in","r",stdin);
  50. //freopen("fish.out","w",stdout);
  51. n=gi();
  52. for(int i=1;i<=n;++i)x[i]=gi(),y[i]=gi();
  53. for(int i=1;i<=n;++i)
  54. for(int j=i+1;j<=n;++j)
  55. if(y[i]==y[j]){
  56. if(x[i]+x[j]&1)continue;
  57. number k=(number){1,0},b=(number){(x[i]+x[j])/2,1};
  58. if(M.find((line){k,b})==M.end())M[(line){k,b}]=++cnt;
  59. vec[M[(line){k,b}]].push_back(y[i]*2);
  60. }else{
  61. 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])};
  62. if(M.find((line){k,b})==M.end())M[(line){k,b}]=++cnt;
  63. vec[M[(line){k,b}]].push_back(x[i]==x[j]?x[i]*2:y[i]+y[j]);
  64. }
  65. for(int i=1;i<=n;++i){
  66. int m=0;
  67. for(int j=1;j<=n;++j)if(j!=i)s[++m]=(yyb){j,atan2(y[j]-y[i],x[j]-x[i])};
  68. std::sort(s+1,s+m+1);
  69. for(int i=1;i<=m;++i)s[i+m]=s[i],s[i+m].at2+=pi*2;
  70. mmp.clear();
  71. res=0;nowi=i;
  72. for(int j=1,p=0,q=0;j<=m;++j){
  73. while(s[p+1].at2+eps<s[j].at2+1.5*pi)insert(s[++p].i);
  74. while(s[q+1].at2<s[j].at2+0.5*pi+eps)delet(s[++q].i);
  75. tail[s[j].i][i]=res;
  76. }
  77. }
  78. for(int i=1;i<=cnt;++i)std::sort(vec[i].begin(),vec[i].end());
  79. ll ans=0;
  80. for(int i=1;i<=n;++i)
  81. for(int j=i+1;j<=n;++j){
  82. int xa=y[i],xb=y[j];
  83. if(xa==xb)xa=x[i],xb=x[j];
  84. if(xa>xb)std::swap(xa,xb);
  85. number k,b;
  86. if(x[i]==x[j])k=(number){1,0},b=(number){x[i],1};
  87. 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]};
  88. if(M.find((line){k,b})==M.end())continue;
  89. int veci=M[(line){k,b}];
  90. 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]);
  91. }
  92. printf("%lld\n",ans*4);
  93. return 0;
  94. }

HNOI2019 鱼 fish的更多相关文章

  1. [HNOI2019]鱼

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

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

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

  3. luogu P5286 [HNOI2019]鱼

    传送门 这题真的牛皮,还好考场没去刚( 这题口胡起来真的简单 首先枚举D点,然后对其他所有点按极角排序,同时记录到D的距离.然后按照极角序枚举A,那么鱼尾的两个点的极角范围就是A关于D对称的那个向量, ...

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

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

  5. 个人对【依赖倒置(DIP)】、【控制反转(IOC)】、【依赖注入(DI)】浅显理解

    一.依赖倒置(Dependency Inversion Principle) 依赖倒置是面向对象设计领域的一种软件设计原则.(其他的设计原则还有:单一职责原则.开放封闭原则.里式替换原则.接口分离原则 ...

  6. 人工鱼群算法超详细解析附带JAVA代码

    01 前言 本着学习的心态,还是想把这个算法写一写,给大家科普一下的吧. 02 人工鱼群算法 2.1 定义 人工鱼群算法为山东大学副教授李晓磊2002年从鱼找寻食物的现象中表现的种种移动寻觅特点中得到 ...

  7. 第三十篇 面向对象的三大特性之继承 supre()

    继承 一 .什么是继承? 类的继承跟现实生活中的父.子.孙子.重孙子的继承关系一样,父类又称基类. Python中类的继承分为:单继承 和  多继承. # 定义父类 class ParentClass ...

  8. Unity基础:AR(增强现实)的学习

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...

  9. 【loj3054】【hnoi2019】鱼

    题目 描述 ​ 难以描述.......慢慢看..: ​ https://loj.ac/problem/3054 范围 ​ $6 \le n \le 1000  ,  1 \le |x| , |y| \ ...

随机推荐

  1. ::before和::after伪元素的妙用

    场景: 假如有一天,你的在写一个前端项目,是关于一份点餐商家电话信息表,你啪塔啪塔地写完了,突然间项目经理跑过来找你,要求你在每一个商家的电话号码前都添加一个电话符号,来使得电话号码更直观和页面更美观 ...

  2. redis介绍 (8) window 下redis的集群(cluster命令)

    前言: 前段时间我在centos上搭建过一次redis集群,那是借助ruby搭建,这次我介绍一种纯redis集群命令的方式去搭建[最后我会简单介绍ruby搭建]. redis集群搭建(三主三备): 准 ...

  3. scala spark 机器学习初探

    Transformer: 是一个抽象类包含特征转换器, 和最终的学习模型, 需要实现transformer方法 通常transformer为一个RDD增加若干列, 最终转化成另一个RDD, 1. 特征 ...

  4. 洗礼灵魂,修炼python(53)--爬虫篇—urllib模块

    urllib 1.简介: urllib 模块是python的最基础的爬虫模块,其核心功能就是模仿web浏览器等客户端,去请求相应的资源,并返回一个类文件对象.urllib 支持各种 web 协议,例如 ...

  5. 洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块

    定制魔法方法 1.什么是定制魔法方法 首先定制是什么意思呢?其实就是自定义了,根据我们想要的要求来自定义.而在python中,其实那些所谓的内置函数,内置方法,内置属性之类的其实也是自定义出来的,不过 ...

  6. forfiles命令详解

    目录复制命令: xcopy   //server/bak/*.*    d:/serverbak /s /e /v /c / d /y /h             at 05:30 shutdown ...

  7. 读取HTML文件进行格式化解析

    #读取HTML文件进行格式化解析 $html = New-Object -ComObject "HTMLFile"; $source = Get-Content -Path &qu ...

  8. [HDFS_add_2] SecondaryNameNode 滚动 NameNode 数据流程

    0. 说明 在 将 SecondaryNameNode 配置到 s105 节点上 的基础上进行 SecondaryNameNode 滚动 NameNode 数据流程 分析 1. SecondaryNa ...

  9. 软件工程实践_Task2_sudoku

    软工实践_Task2 标签(空格分隔): 软工实践 相关要求:第二次作业--个人项目实战 github:传送门 解题思路 先是一点杂谈. 首先,看完作业要求之后,心里先有个大概的框架. 语言:C++ ...

  10. 数据挖掘十大算法--K-均值聚类算法

    一.相异度计算  在正式讨论聚类前,我们要先弄清楚一个问题:怎样定量计算两个可比較元素间的相异度.用通俗的话说.相异度就是两个东西区别有多大.比如人类与章鱼的相异度明显大于人类与黑猩猩的相异度,这是能 ...