HDU 5738 Eureka
题目大意:
给出平面上的 $n$ 个点,每个点有唯一的标号(label),这 $n$ 个标号的集合记作 $S$,点可能重合。求满足下列条件的 $S$ 的子集 $T$ 的数目:
1. $|T|\ge 2$
2. $T$中的点共线
Solution:
只包含一种点的符合条件的子集 $T$ 的数目很容易计算,以下我们只考虑其中至少有两种不同(指坐标不同,下同)点的符合条件的子集$T$(以下简称子集)的数目。
考虑过两不同点 $u, v$ 的直线上的点,将这些点的集合记作 $P_{uv}$,考虑 $P_{uv}$ 的子集对答案的贡献 $C_{u,v}$ 。
设 $|P_{uv}|=k$,则 $C_{uv}=2^k-k-1-\text{single}(P_{uv})$,其中 $\text{single}(P_{uv})$ 指 $P_{uv}$ 的只包含一种点的子集 $T$ 的数目。
现在固定 $u$,计算一共能得到几个 $P_{uv}$。这可通过以 $u$ 为基点,对(去重后的)其他点作极角排序来做到。
以每个点为基点做一次极角排序,这样每个点集 $P_{uv}$ 都被重复计算了 $|P_{uv}|$ 次。
我们用 $f[k]$ 表示模为 $k$ 的点集 $P_k$ 出现的次数。这个次数被重复计算了$k$次,$P_k$出现的次数为$\frac{f[k]}{k}$
则所有$P_k$贡献的子集的数目为
\[\frac{f[k]}{k}(2^k-k-1)-\sum\limits_{P_k}\text{single}(P_k),\]
故总计数为
\[\sum_{k=2}^{n}{\frac{f[k]}{k} 2^k-(k+1)} -\sum_{k=2}^{n}{\sum\limits_{P_k}\text{single}(P_k)}\]
为了计算$\sum_{k=2}^{n}{\sum\limits_{P_k}\text{single}(P_k)}$,另外维护一个数组 $d$,$d[u]$ 表示 $u$ 在多少个点集 $P$ 中出现过。
从而有
\[\sum_{k=2}^{n}{\sum_{P_k}\text{single}(P_k)}=\sum_{u=1}^{m}d[u]*(2^{c[u]}-c[u]-1),\]
其中 $m$ 指去重后的点数,$c[u]$ 表示与 $u$ 重合的点数。
Implement:
#include <bits/stdc++.h>
using namespace std; const int N(1e3+);
typedef long long LL;
LL mod=1e9+; struct point{
LL x, y;
void read(){
scanf("%lld%lld", &x, &y);
}
point operator-(const point &b)const{
return {x-b.x, y-b.y};
}
point operator-(){
return {-x, -y};
}
bool operator==(const point &b)const{
return x==b.x && y==b.y;
}
bool operator<(const point &b)const{
return x==b.x?y<b.y:x<b.x;
}
void out(){
cout<<x<<' '<<y<<endl;
}
LL operator^(const point &p)const{
return x*p.y-y*p.x;
}
}a[N], slope[N]; bool cmp(const int &a, const int &b){
return (slope[a]^slope[b])<; //error-prone
} int cnt[N], b[N], dup[N]; LL num[N], p[N]={}; int main(){ int T, n;
for(int i=; i<=; i++) p[i]=(p[i-]<<)%mod; for(scanf("%d", &T); T--; ){
scanf("%d", &n);
for(int i=; i<n; i++)
a[i].read(); sort(a, a+n);
for(int i=, j=, k=; i<n; j++, k=i){
for(; i<n && a[i]==a[k]; i++);
cnt[j]=i-k;
} int e=unique(a, a+n)-a; memset(num, , sizeof(num));
memset(dup, , sizeof(dup)); for(int i=; i<e; i++){ for(int j=, k=; j<e; j++){
if(i==j) continue;
slope[j]=a[j]-a[i];
if(slope[j].x<) slope[j]=-slope[j];
else if(slope[j].x== && slope[j].y<) slope[j]=-slope[j];
b[k++]=j;
} sort(b, b+e-, cmp); for(int j=, k=, sum; j<e-; k=j){
for(sum=; j<e- && (slope[b[j]]^slope[b[k]])==; sum+=cnt[b[j++]]);
num[sum+cnt[i]]+=cnt[i]; //error-prone
dup[i]++;
}
} LL _dup=, res=; for(int i=; i<e; i++) _dup+=dup[i]*(p[cnt[i]]-cnt[i]-+mod), _dup%=mod;
for(int i=; i<e; i++) res+=p[cnt[i]]-cnt[i]-+mod, res%=mod;
for(int i=; i<=n; i++)
num[i]/=i, res+=num[i]*(p[i]-i-+mod), res%=mod;
res+=mod-_dup, res%=mod;
printf("%lld\n", res);
}
}
UPD
在以某个点为基点进行极角排序需要进行一个将待排序的向量规范化(formalization)的过程, 具体的说就是保证各向量满足:
x>0 或 x==0 && y>0 (待排序都是非零向量)
题解上给出的做法更好一些:
想将输入的点去重后,按照字典序排序, 然后从左到右扫, 当扫到第$i$个点$p_i$时我们统计由$p_i$及其右面的点构成的且一定包含$p_i$的共线子集的数目, 统计的方法和前面类似.
这样做的好处是
1. 向量自然规范化
2. 不重不漏
Implementation:
HDU 5738 Eureka的更多相关文章
- HDU 5738 Eureka 统计共线的子集个数
Eureka 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5738 Description Professor Zhang draws n poin ...
- HDU 5738 Eureka(极角排序)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5738 [题目大意] 给出平面中一些点,在同一直线的点可以划分为一个集合,问可以组成多少包含元素不少 ...
- hdu 5738 Eureka 极角排序+组合数学
Eureka Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- hdu 5738 2016 Multi-University Training Contest 2 Eureka 计数问题(组合数学+STL)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5738 题意:从n(n <= 1000)个点(有重点)中选出m(m > 1)个点(选出的点只 ...
- 2016 Multi-University Training Contest 2题解报告
A - Acperience HDU - 5734 题意: 给你一个加权向量,需要我们找到一个二进制向量和一个比例因子α,使得|W-αB|的平方最小,而B的取值为+1,-1,我们首先可以想到α为输入数 ...
- 2016 Multi-University Training Contest 2 - 1005 Eureka
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5738 题目大意:给定平面上的n个点,一个集合合法当且仅当集合中存在一对点u,v,对于集合中任意点w,均 ...
- HDU 3746:Cyclic Nacklace(KMP循环节)
Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
随机推荐
- log4j导致的性能问题
问题背景 双十一零点时,有一个服务A(后文该服务都用A来代替)的tp99由平常的50ms左右突然彪到60000ms,导致调用端积累了几十W的数据,同时,也影响到了同一个docker上的其他服务.那为什 ...
- RMQ(ST算法)
RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列a,回答若干询问RMQ(A,i,j)(i, j<=n),返回数列a中下标在i ...
- sublime 函数跳转插件 — ctags 安装和使用
ctags 是 sublime 下一个函数跳转的插件,可以让你方便地从函数调用的位置跳到函数定义的位置.相对于其他插件,ctags 的安装稍微有点复杂,这里记录下备忘. 首先,假设已经安装 Packa ...
- MVC+EF 理解和实现仓储模式和工作单元模式
MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generi ...
- jquery 选择器大全
jquery 选择器大体上可分为4 类: 1.基本选择器 2.层次选择器 3.过滤选择器 4.表单选择器 其中过滤选择器可以分为: 1.简单过滤选择器 2.内容过滤选择器 3.可见性过滤选择器 4.属 ...
- Vmware player 12
免费版的虚拟机Vmware,体积小.运行快速... 官方下载界面 下载地址: http://yunpan.cn/cm5smywVvqS8V 访问密码 35ac 官方下载:点击下载
- ListView简介
说起来,简介这种东西我一般都会去百度,不过似乎这样太没诚意了.╮(╯▽╰)╭ 没办法我再去查查别的资料 官方API,说的啥呢?经过一番研究我终于读懂了....╮(╯▽╰)╭ (让一个英语三级的学渣来分 ...
- 1017关于EXPLAIN的语法
转自博客 http://blog.csdn.net/zhuxineli/article/details/14455029 explain显示了MySQL如何使用索引来处理select语句以及连接表.可 ...
- ClipDrawable 实现图片渐变现实
clip.xml <?xml version="1.0" encoding="utf-8"?><clip xmlns:android=&quo ...
- JAVA file文件操作
/** *文件重命名 * @param oldname 原来的文件名 * @param newname 新文件名 */ @RequestMapping("renameFile") ...