HDU 6022---MG loves set(K-D树)
if the sum of the square of every element in a set is less than or equal to the square of the sum of all the elements, then we regard this set as ”A Harmony Set”.
Now we give a set with n different elements, ask you how many nonempty subset is “A Harmony Set”.
MG thought it very easy and he had himself disdained to take the job. As a bystander, could you please help settle the problem and calculate the answer?
And as for each case, there are 1 integer n in the first line which indicate the size of the set(n<=30).
Then there are n integers V in the next line, the x-th integer means the x-th element of the set(0<=|V|<=100000000).
There should be one integer in the line which represents the number of “Harmony Set”.

思路:
看到题目数据的范围n<=30 ,枚举考虑每一个子集肯定会超时,所以这个办法不行了。怎么样降低复杂度呢?
先化简一下,设子集为{x,y,z}满足题目要求,则x*x+y*y+z*z<=(x+y+z)*(x+y+z) 即xy+yz+xz>=0 ,所以本题就是求一个集合有多少非空子集满足集合中元素两两乘积的和大于等于0;
巧妙地思想:把集合分成前后两半,设前一半集合的任意一个子集的和为Xi 两两之间乘积的和为Yi ,后一半集合的任意一个子集的和为Xj 两两之间乘积的和为Yj 可以发现(a+b)*(c+d)+ab+cd>=0是子集{a,b,c,d}满足题意的要求,那么Xi*Xj+Yi+Yj>=0就是判断当前由这两个子集合起来得到的子集是否满足题意的要求。最后用K-D树优化即可。
官方题解如下:
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
const int N=;
LL a[];
int flag[*N];
int idx; struct Node
{
LL f[];
LL mx[];
LL mn[];
int size;
bool operator<(const Node& s)const
{ return f[idx]<s.f[idx]; }
}A[N],B[N],tr[*N]; void update(int i)
{
int s=;
if(flag[i<<])
{
for(int k=;k<=;k++)
{
if(tr[i<<].mn[k]<tr[i].mn[k]) tr[i].mn[k]=tr[i<<].mn[k];
if(tr[i<<].mx[k]>tr[i].mx[k]) tr[i].mx[k]=tr[i<<].mx[k];
}
s+=tr[i<<].size;
}
if(flag[i<<|])
{
for(int k=;k<=;k++)
{
if(tr[i<<|].mn[k]<tr[i].mn[k]) tr[i].mn[k]=tr[i<<|].mn[k];
if(tr[i<<|].mx[k]>tr[i].mx[k]) tr[i].mx[k]=tr[i<<|].mx[k];
}
s+=tr[i<<|].size;
}
tr[i].size=s;
} void build(int l,int r,int i,int deep)
{
if(l>r) return;
int mid=(l+r)>>;
idx=deep;
flag[i]=;
flag[i<<]=; flag[i<<|]=; nth_element(B+l,B+mid,B+r+);
for(int k=;k<=;k++)
tr[i].mx[k]=tr[i].mn[k]=tr[i].f[k]=B[mid].f[k]; build(l,mid-,i<<,-deep);
build(mid+,r,i<<|,-deep);
update(i);
}
int check(LL x1,LL y1,LL x2,LL y2)
{
if(x1*x2+y1+y2>=) return ;
return ;
}
int count(Node p,int i)
{
int re=;
re+=check(tr[i].mn[],tr[i].mn[],p.f[],p.f[]);
re+=check(tr[i].mn[],tr[i].mx[],p.f[],p.f[]);
re+=check(tr[i].mx[],tr[i].mn[],p.f[],p.f[]);
re+=check(tr[i].mx[],tr[i].mx[],p.f[],p.f[]);
return re;
}
int query(Node p,int i)
{
if(!flag[i]) return ;
if(count(p,i)==) return tr[i].size;
int re=check(p.f[],p.f[],tr[i].f[],tr[i].f[]);
if(count(p,i<<)) re+=query(p,i<<);
if(count(p,i<<|)) re+=query(p,i<<|);
return re;
} int main()
{
int T;
cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%lld",&a[i]);
int mid=n/;
int tt=(<<mid);
int tot1=,tot2=;
for(int i=;i<=tt-;i++)
{
A[tot1].f[]=;
A[tot1].f[]=;
for(int k=;(<<(k-))<tt;k++)
{
if((<<(k-))&i)
{
A[tot1].f[]+=A[tot1].f[]*a[k];
A[tot1].f[]+=a[k];
}
}
tot1++;
}
int tt2=<<n;
for(int i=;i<tt2;i+=tt)
{
B[tot2].f[]=;
B[tot2].f[]=;
for(int k=mid+;(<<(k-))<tt2;k++)
{
if((<<(k-))&i)
{
B[tot2].f[]+=B[tot2].f[]*a[k];
B[tot2].f[]+=a[k];
}
}
tot2++;
}
/*for(int i=0;i<tot1;i++)
cout<<A[i].f[0]<<" "<<A[i].f[1]<<endl;
cout<<"-----------------"<<endl;
for(int i=0;i<tot2;i++)
cout<<B[i].f[0]<<" "<<B[i].f[1]<<endl;*/
build(,tot2-,,);
int ans=-;
for(int i=;i<tot1;i++)
{
ans+=query(A[i],);
}
printf("%d\n",ans);
}
return ;
}
HDU 6022---MG loves set(K-D树)的更多相关文章
- hdu 5274 Dylans loves tree(LCA + 线段树)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- hdu 6020 MG loves apple 恶心模拟
题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Ja ...
- hdu 6021 MG loves string
MG loves string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others ...
- hdu 6021 MG loves string (一道容斥原理神题)(转)
MG loves string Accepts: 30 Submissions: 67 Time Limit: 2000/1000 MS (Java/Others) Memory ...
- hdu 5195 DZY Loves Topological Sorting 线段树+拓扑排序
DZY Loves Topological Sorting Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...
- HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)
题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...
- hdu 5269 ZYB loves Xor I(字典树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5269 思路分析:当lowbit(AxorB)=2p 时,表示A与B的二进制表示的0-p-1位相等,第p ...
- hdu 5649 DZY Loves Sorting 二分+线段树
题目链接 给一个序列, 两种操作, 一种是将[l, r]里所有数升序排列, 一种是降序排列. 所有操作完了之后, 问你a[k]等于多少. 真心是涨见识了这题..好厉害. 因为最后只询问一个位置, 所以 ...
- HDU 5269 ZYB loves Xor I Trie树
题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5269 bc:http://bestcoder.hdu.edu.cn/contests/con ...
- ●HDU 6021 MG loves string
题链: http://acm.hdu.edu.cn/showproblem.php?pid=6021 题解: 题意:对于一个长度为 N的由小写英文字母构成的随机字符串,当它进行一次变换,所有字符 i ...
随机推荐
- day39 mysql数据库基本操作
什么是数据库 用来存储数据的仓库 数据库可以在硬盘及内存中存储数据 主要学习硬盘中存储数据,因为内存中的数据总有一天会丢失 数据库与文件存储数据区别 (公司的开发是综合内容的) 数据库本质也是通过文件 ...
- toastr简单用法及修改垂直居中
toastr是一个基于Jquery简单.漂亮的消息提示插件,使用简单.方便,可以根据设置的超时时间自动消失. 1.使用很简单,首选引入toastr的js.css文件html <script sr ...
- D. Kilani and the Game(多源BFS)
题目来源:http://codeforces.com/contest/1105/problem/D 题意:编号为1-k的点在一张n*m的表格中依次扩散,每个结点有各自的扩散速度且只可以往上下左右四个方 ...
- node.js中express的Router路由的使用
express中的Router作用就是为了方便我们更好的根据路由去分模块.避免将所有路由都写在入口文件中. 一.简单的使用Router const express = require('express ...
- 让.net core 支持静态文件
想不到默认的.net core竟然不支持静态文件,还需要额外配置中间件来支持 1.Nuget安装 Microsoft.aspnetcore.staticfiles 2.在Startup.cs中使用服 ...
- jxl操作excel写入数据不覆盖原有数据示例
public void readTO() { Workbook wb = null; WritableWorkbook wwb = null; try { ...
- springboot swagger 整合
Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步. 作用: 1. ...
- using五大用法
1.命名空间 using namespace 命名空间;//这样每次使用命名空间中的变量时就不用指定命名空间了 注意:头文件中不应有using命名空间的声明 2.类型别名(C++11) using a ...
- Android开发之Activity
活动(Activity) 活动是最容易吸引用户的地方,它是一种可以包含用户界面的组件,主要用于和用户交互. FirstActivity 手动创建活动 新建一个project,不再选择empty act ...
- 1018 Public Bike Management
There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...