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 ...
随机推荐
- python中assert详解
assert基础 官方解释:"Assert statements are a convenient way to insert debugging assertions into a pro ...
- python基础 ---- 使用pyCharm 调试
debug -- 为了分析程序的异常 单步调试 1.设置断点 2.debug.启动 3.监控变量
- JAVA中字符串操作几种方式对比
@参考文章 方法及原理: 方法1:a=a+b实际上另开辟一个空间c=a+b;然后将c的引用赋给a 方法2:a += b实际上是建立一个StringBuffer,然后调用append(),最后再将Str ...
- Percentage&Last zero&Convert from char to float
Percentage g_rate = wg_header-rate. condense g_rate. SHIFT g_rate RIGHT DELETING TRAILING '0'. REPLA ...
- C# 检测证书是否安装、 安装证书
检测是否存在指定的证书: /// <summary> /// 检测是否存在指定的证书 /// </summary> /// <returns></return ...
- day 6 元组、字典、字符串
本节内容 : 1,元组 2,字典 3,字符串作业 produce = [('mac', 9000), ('bicycle', 800), ('computer', 8000), ('book', 50 ...
- C++ 提取网页内容系列之一
标 题: C++ 提取网页内容系列作 者: itdef链 接: http://www.cnblogs.com/itdef/p/4171179.html 欢迎转帖 请保持文本完整并注明出处 首先分析网页 ...
- MySQL InnoDB特性:两次写(Double Write)
http://www.ywnds.com/?p=8334 一.经典Partial page write问题? 介绍double write之前我们有必要了解partial page write(部分页 ...
- tensorflow学习之(五)构造简单神经网络 并展示拟合过程
# def 添加层 如何构造神经网络 并展示拟合过程 import tensorflow as tf import numpy as np import matplotlib.pyplot as pl ...
- Spring 的属性注入
一.注入方式 (1)set方法注入 (2)构造函数注入 (3)p名称空间注入 (4)spel注入 二.复杂类型注入