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 ...
随机推荐
- gridView 删除一行后自动定位到指定行
/// <summary> /// 删除后定位到某一行 /// </summary> /// <param name="aCode"></ ...
- 10.13 新版本go on~
上午1.5 终审 and 排期 合同管理那边又是切换选项时各种联动,我第一想法是 好麻烦,不想做这个...第二想法才是给我做吧 锻炼锻炼我 然后 分任务的时候 分给我了,,哈哈 开心 虽然我没想躲 但 ...
- [leetcode]95. Unique Binary Search Trees II给定节点形成不同BST的集合
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ...
- stark组件开发之添加按钮显示和URL
添加: 需求: 根据用户的权限, 决定是否,有添加按钮. 通过配置进行定制,预留钩子进行权限的判断. class StartHandler(object): .................... ...
- http协议和四个层之间的关系
TCP/IP协议的分层:应用层.传输层.网络层.数据链路层. ····应用层···· 决定了向用户提供应用服务时通信的活动.HTTP协议存在于该层.(FTP文件传输协议,DNS域名系统) ....传输 ...
- exchange 2010 数据库管理
1. 查看数据库中空白空间 Get-MailboxDatabase databasename -Status | FL AvailableNewMailboxSpace 2.卸载数据库 Dismoun ...
- delphi三层结构常出现的问题和解决方案
以下问题出现原因有可能多个,暂时将我遇见的记录下来,以后有新的在陆续更新上去,有网友愿意的话也可以共同测试一下. 一,无法更新定位行.一些值可能已在最后一次读取已更改. 错误出现前提: 1, 录数据时 ...
- SQL 不常用的一些命令sp_OACreate,xp_cmdshell,sp_makewebtask
开启和关毕xp_cmdshell EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cm ...
- VM下载安装
VM下载 VM是一款收费软件,要找有密钥的下载. 我的网盘 > 软件 > 常用电脑工具 > VM VM安装 参考链接中的安装步骤 http://blog.java1234.com/b ...
- VS中编译出现——计算机中丢失XINPUT1_4.dll解决办法
如果用DX SDK 2010的版本,编译时可能就会出现这种问题. 解决办法,在链接库时把XInput.lib换成XINPUT9_1_0.LIB,重新编译就可以了. 用老操作系统 + 老DX SDK + ...