题目链接

Problem Description
MG is an intelligent boy. One day he was challenged by the famous master called Douer: 
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?
 
Input
The first line is an integer T which indicates the case number.(1<=T<=10)
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).
Output
As for each case, you need to output a single line.
There should be one integer in the line which represents the number of “Harmony Set”. 
Sample Input
3
4
1 2 3 4
5
1 -1 2 3 -3
6
0 2 4 -4 -5 8
 
Sample Output
15
12
25
 
题意:

思路:

看到题目数据的范围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树)的更多相关文章

  1. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  2. hdu 6020 MG loves apple 恶心模拟

    题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Ja ...

  3. hdu 6021 MG loves string

    MG loves string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others ...

  4. hdu 6021 MG loves string (一道容斥原理神题)(转)

    MG loves string    Accepts: 30    Submissions: 67  Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  5. hdu 5195 DZY Loves Topological Sorting 线段树+拓扑排序

    DZY Loves Topological Sorting Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...

  6. HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)

    题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...

  7. hdu 5269 ZYB loves Xor I(字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5269 思路分析:当lowbit(AxorB)=2p 时,表示A与B的二进制表示的0-p-1位相等,第p ...

  8. hdu 5649 DZY Loves Sorting 二分+线段树

    题目链接 给一个序列, 两种操作, 一种是将[l, r]里所有数升序排列, 一种是降序排列. 所有操作完了之后, 问你a[k]等于多少. 真心是涨见识了这题..好厉害. 因为最后只询问一个位置, 所以 ...

  9. 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 ...

  10. ●HDU 6021 MG loves string

    题链: http://acm.hdu.edu.cn/showproblem.php?pid=6021 题解: 题意:对于一个长度为 N的由小写英文字母构成的随机字符串,当它进行一次变换,所有字符 i ...

随机推荐

  1. EasyUI datagrid单元格文本超出显示省略号,鼠标移动到单元格显示文本

    nowrap : true;  是前提 $('#×××').datagrid({ nowrap : true,//设置为true,当数据长度超出列宽时将会自动截取 }); 省略号样式: <sty ...

  2. 396. Rotate Function 移动加权求和,取最大值

    [抄题]: Given an array of integers A and let n to be its length. Assume Bk to be an array obtained by ...

  3. .net like模糊查询参数化

    List<SqlParameter> paras = new List<SqlParameter>(); if (!string.IsNullOrEmpty(ciName)) ...

  4. Java 数组元素合并并去重

    public class TestList { public static void main(String[] args) { Set<Integer> set = new TreeSe ...

  5. Spring 系列目录

    Spring(https://spring.io/) 系列目录 第一篇:Spring 系列 第一章 Spring Core (1) Convert 1.1.1 Spring ConversionSer ...

  6. 操作系统学习笔记(三) windows内存管理

    //系统物理页面是由 (Page Frame Number Database )简称PFN数据库来进行管理,实际上是一个数组,每个物理页面都对应一个PFN项. 进程的地址空间是通过VAD(Virtua ...

  7. 基于akka-http搭建restfull框架

    1.scala开发环境介绍 2.scala插件的demo模板介绍 3.akka-http提供demo研究 4.添加路由机制解析 package org.netsharp.rest import akk ...

  8. 亲写javascript 各类面试题

    DOM修改: 1.全文单词首字母大写---2013 腾讯 var toCapitalize = function (str){ var aStr1 = str.split(" ") ...

  9. Python10/24--组合/封装/property装饰器/多态

    组合的应用: 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之为组合 2. 为何用组合 组合也是用来解决类与类代码冗余的问题 3. 如何用组合 '''class Foo: aaa=111 ...

  10. C++ MFC棋牌类小游戏day6

    双人单机小游戏做完了,规则那部分还没介绍,暂时不打算介绍了,因为写的这个bug太多,我打算重新修改. 链接:https://pan.baidu.com/s/1XQKPSv0Tw36Qi2TeaRJiM ...