LOJ#3054. 「HNOI 2019」鱼

https://loj.ac/problem/3054

题意

  • 平面上有n个点,问能组成几个六个点的鱼。(n<=1000)

分析

鱼题,劲啊。

  • 容易想到先枚举这个\(D\),然后极角序排一下,我们枚举\(A\),对\(B,E,F\)分别统计。
  • 枚举\(A\)的过程中用一个指针维护\(E,F\)的范围,对答案贡献是一个\(\sum\binom{x}{2}\)的形式,容易维护。
  • 然后现在要求\(B\)的方案数,可以发现符合条件的\(BC\)一定满足线段\(AD\)垂直平分线段\(BC\)。
  • 不难想到,预处理出来每条类似\(BC\)这样的线段,求出他们被垂直平分时那个直线的\(a,b,c\),同时因为\(AD,BC\)应有交,还需要存一个中点横坐标\(X_{mid}\),然后枚举\(A\)时用\([L=X_A,R=X_D]\)算一下这之间有多少个点。然后可能有横坐标相等的情况,所以我又预处理的每条线段中点的纵坐标的信息。
  • 然后就做完了,注意一下精度。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
#define N 2050
typedef double f2;
typedef long long ll;
const f2 eps=1e-10;
const f2 pi=acos(-1);
ll ans;
int c[N],n,lb,len[N];
ll rlen[N],V[N];
ll pf(ll x) {return x*x;}
ll gcd(ll x,ll y) {return y?gcd(y,x%y):x;}
struct Point {
ll x,y;
Point(){}
Point(ll x_,ll y_) {x=x_,y=y_;}
Point turn90(const Point &p) const {
Point re,t=*this-p;
re.x=-t.y;
re.y=t.x;
return re+p;
}
void prt() {
printf("%lld %lld\n",x,y);
}
Point operator + (const Point &u) const {return Point(x+u.x,y+u.y);}
Point operator - (const Point &u) const {return Point(x-u.x,y-u.y);}
Point operator / (const ll &rate) const {return Point(x/rate,y/rate);}
ll operator | (const Point &u) const {return (x*u.y-y*u.x);}
ll operator & (const Point &u) const {return (x*u.x+y*u.y);}
}a[N];
struct Pop {
Point p; f2 k;
Pop() {}
Pop(Point p_,f2 k_) {p=p_,k=k_;}
bool operator < (const Pop &u) const {
return k<u.k;
}
}b[N<<1];
struct B {
ll a,b,c,x;
void prt() {
printf("%lld %lld %lld %lld\n",a,b,c,x);
}
bool operator < (const B &u) const {
if(a==u.a) {
if(b==u.b) {
if(c==u.c) {
return x<u.x;
}else return c<u.c;
}else return b<u.b;
}else return a<u.a;
}
};
ll Abs(ll x) {return x>0?x:-x;}
vector<B> S,T;
B calc(Point p1,Point p2) {
ll dy=p2.y-p1.y,dx=p2.x-p1.x;
ll ta=-dy,tb=dx;
ll d=gcd(Abs(ta),Abs(tb));
if(d!=1) ta/=d,tb/=d;
if(ta<0) ta=-ta,tb=-tb;
if(ta==0) tb=Abs(tb);
ll tc=ta*p1.x+tb*p1.y;
return (B){ta,tb,tc,0};
}
int main() {
scanf("%d",&n);
int i,j;
for(i=1;i<=n;i++){
scanf("%lld%lld",&a[i].x,&a[i].y); a[i].x<<=1, a[i].y<<=1;
}
for(i=1;i<=n;i++) {
for(j=1;j<=n;j++) if(i!=j) {
Point mid=(a[i]+a[j])/2;
B tmp=calc(a[i].turn90(mid),a[j].turn90(mid));
tmp.x=(a[i].x+a[j].x)/2;
S.push_back(tmp);
tmp.x=(a[i].y+a[j].y)/2;
T.push_back(tmp);
//printf("%d %d %lld %lld %lld\n",i,j,tmp.a,tmp.b,tmp.c);
}
}
sort(S.begin(),S.end());
sort(T.begin(),T.end());
for(i=1;i<=n;i++) {
Point o=a[i];
lb=0;
for(j=1;j<=n;j++) if(i!=j) b[++lb]=Pop(a[j],atan2(a[j].y-a[i].y,a[j].x-a[i].x));
sort(b+1,b+lb+1);
for(j=1;j<=lb;j++) b[j+lb]=b[j],b[j+lb].k+=2*pi;
int ln=lb<<1;
int l=0,r=0;
for(j=1;j<=lb;j++) {
rlen[j]=pf(o.x-b[j].p.x)+pf(o.y-b[j].p.y);
V[j]=rlen[j];
}
sort(V+1,V+lb+1);
int lv=unique(V+1,V+lb+1)-V-1;
for(j=1;j<=lb;j++) len[j]=lower_bound(V+1,V+lv+1,rlen[j])-V;
for(j=1;j<=lb;j++) len[j+lb]=len[j];
for(j=1;j<=lv;j++) c[j]=0;
ll ans1=0,ans2=0;
for(j=1;j<=lb;j++) {
for(;r<=ln&&b[r+1].k+eps<b[j].k+1.5*pi;) r++,ans1+=c[len[r]],c[len[r]]++;
for(;l<=ln&&b[l+1].k<b[j].k+0.5*pi+eps;) l++,c[len[l]]--,ans1-=c[len[l]];
B t=calc(o,b[j].p),tl=t,tr=t;
if(o.x==b[j].p.x) {
tl.x=o.y, tr.x=b[j].p.y;
if(tl.x>tr.x) swap(tl.x,tr.x);
ans2=lower_bound(T.begin(),T.end(),tr)-upper_bound(T.begin(),T.end(),tl);
}else {
tl.x=o.x, tr.x=b[j].p.x;
if(tl.x>tr.x) swap(tl.x,tr.x);
ans2=lower_bound(S.begin(),S.end(),tr)-upper_bound(S.begin(),S.end(),tl);
}
ans2=max(ans2,0ll);
//printf("%lld %lld\n",ans1,ans2);
ans+=ans1*ans2;
}
}
printf("%lld\n",ans<<1);
}

LOJ#3054. 「HNOI 2019」鱼的更多相关文章

  1. 「HNOI 2019」白兔之舞

    一道清真的数论题 LOJ #3058 Luogu P5293 题解 考虑$ n=1$的时候怎么做 设$ s$为转移的方案数 设答案多项式为$\sum\limits_{i=0}^L (sx)^i\bin ...

  2. Solution -「HNOI 2019」「洛谷 P5293」白兔之舞

    \(\mathcal{Description}\)   Link.   不想概括题意.jpg \(\mathcal{Solution}\)   定义点集 \(S_c=\{(u,v)|v=c\}\):第 ...

  3. Loj #2495. 「AHOI / HNOI2018」转盘

    Loj #2495. 「AHOI / HNOI2018」转盘 题目描述 一次小 G 和小 H 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1 ...

  4. Loj #2494. 「AHOI / HNOI2018」寻宝游戏

    Loj #2494. 「AHOI / HNOI2018」寻宝游戏 题目描述 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得 ...

  5. loj#2020 「AHOI / HNOI2017」礼物 ntt

    loj#2020 「AHOI / HNOI2017」礼物 链接 bzoj没\(letex\),差评 loj luogu 思路 最小化\(\sum\limits_1^n(a_i-b_i)^2\) 设改变 ...

  6. LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)

    题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...

  7. LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)

    题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...

  8. LOJ #2540. 「PKUWC 2018」随机算法(概率dp)

    题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...

  9. LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)

    Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...

随机推荐

  1. PWA web应用模型

    2018年的第一篇博客,最近都去挤图书馆了,希望新年新气象... 简介 PWA 是一门Google推出的web前端新技术,全称是Progressive Web App,是Google在2015年提出, ...

  2. poj1679次小生成树入门题

    次小生成树求法:例如求最小生成树用到了 1.2.4这三条边,总共5条边,那循环3次的时候,每次分别不用1.2.4求得最小生成树的MST,最小的MST即为次小生成树 如下代码maxx即求最小生成树时求得 ...

  3. 搞懂分布式技术9:Nginx负载均衡原理与实践

    搞懂分布式技术9:Nginx负载均衡原理与实践 本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容, ...

  4. 阅读《大型网站技术架构:核心原理与案例分析》第五、六、七章,结合《XXX重大技术需求征集系统》,列举实例分析采用的可用性和可修改性战术,将上述内容撰写成一篇1500字左右的博客阐述你的观点。

    这三章主要讲述的是网站的可用性.伸缩性和可扩展性. 首先,网站的可用性描述网站可有效访问的特性,相比于网站的其他非功能特性,网站的可用性更容易引起人们的注意,尤其是大型网站的可用性,如果大公司的网站出 ...

  5. Git 的origin和master分析(转)

    转:http://lishicongli.blog.163.com/blog/static/1468259020132125247302/ 首先要明确一点,对git的操作是围绕3个大的步骤来展开的(其 ...

  6. 【Error】IOError: [Errno 22] invalid mode

    使用python打开或写入文件时会报以下错误IOError: [Errno 22] invalid mode,比如打开f:\nnpm.txt时,可以在地址前面加上r或R,即r'f:\nnpm.txt' ...

  7. 十一、dbms_random(随机数生成器)

    1.概述 提供了内置的随机数生成器,可以用于快速生成随机数. 2.包的组成 1).initialize作用:用于初始化dbms_random包,必须提供随机数种子.语法:dbms_random.ini ...

  8. C#中使用GUID

    GUID(全局统一标识符)是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.通常平台会提供生成GUID的API.生成算法很有意思,用到了以太网卡地址.纳秒级时间.芯片ID码和许多可 ...

  9. The disadvantage for manager has a part-time job as a trainer

    At present, most companies with in-house trainers take the development model of "full-time trai ...

  10. Laravel 文件夹结构简介

    表 1.1:Laravel 文件夹结构简介 文件夹名称 简介 app 应用程序的业务逻辑代码存放文件夹 app/Console 存放自定义 Artisian 命令文件 app/Http/Control ...