【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=6022

【题意】



让你求一个集合的子集数目;

这个子集有要求;

即:

它所有元素的平方的和小于它所有元素的和的平方。

【题解】



假设一个集合大小为3元素为a1,a2,a3



a12+a22+a32<=(a1+a2+a3)2

化简一下可以得到

a1∗a2+a1∗a3+a2∗a3>=0

所以原限制条件其实可以转化为一个集合里面任意两个数的乘积的和大于等于0;

但是你不好直接去枚举这个集合的子集;

->有230的规模

这里用到了meet-in-the-middle这种方法(自行百度);

先处理215规模的;

即把整个序列分成等大的两部分;

先处理前面一半;

这前面一半;

枚举每个元素在不在子集当中;

然后算出每个子集的所有元素的和sumA

sumA=a1+a2+a3..+al

以及sqrsumA

sqrsumA=a12+a22+a32+...+al2

然后把

(sumA,(sumA2−sqrsumA)/2)

当成一个点来对待->(x,y)

注意这里的y其实就是A集合中任意两个数的乘积

然后把这个点存在kd-tree里面,并以这些点构建出一棵kd-tree;

然后再枚举序列的右半部分;

即n/2+1..n这一段

同样枚举这一段每个元素在不在子集中;

->这样又有了另外一个子集B

同样处理出sumB

sumB=b1+b2+b3..+bl

以及sqrsumB

sqrsumB=b12+b22+b32+...+bl2

然后同样的处理出下面这个点

(sumB,(sumB2−sqrsumB)/2)

这里的y变成是B集合的任意两个元素的乘积了;

然后考虑把B集合和之前的某个A集合合在一起;

那么我们要怎么搞出那个新的集合的任意两个元素的乘积呢;

那就是sumA*sumB+ya+yb了

这里sumA*sumB=a1*b1+a1*b2….

ya就是A集合任意两个数乘积的和,yb就是…

你想想两个集合连在一起后会变成什么样?

懂了吧;

所以我们现在的问题就转化为;

已经知道了直线

k*x+b+y的两个参数k和b;

然后(x,y)是A集合的那两个参数泛化成的坐标;

然后要求满足k*x+b+y>=0的(x,y)的个数;

用kd-tree能够轻松的搞定这个问题;

因为最后有两个集合都是空集的情况,所以答案要减1。



【完整代码】

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define LL long long
  6. #define rep1(i,a,b) for (int i = a;i <= b;i++)
  7. #define rep2(i,a,b) for (int i = a;i >= b;i--)
  8. #define mp make_pair
  9. #define ps push_back
  10. #define fi first
  11. #define se second
  12. #define rei(x) scanf("%d",&x)
  13. #define rel(x) scanf("%lld",&x)
  14. #define ref(x) scanf("%lf",&x)
  15. #define pd(a,b,c) (a*c.d[0]+b+c.d[1]>=0)
  16. typedef pair<int, int> pii;
  17. typedef pair<LL, LL> pll;
  18. const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
  19. const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
  20. const double pi = acos(-1.0);
  21. const int N = 33;
  22. const int MAXN = 65540;
  23. int n,now,root;
  24. LL a[N];
  25. struct point
  26. {
  27. int n,sie, l, r;
  28. LL d[2],mi_n[2],ma_x[2];
  29. };
  30. point t[MAXN];
  31. bool cmp_1(point a, point b)
  32. {
  33. return a.d[now] < b.d[now];
  34. }
  35. void gengxin(int father, int son)
  36. {
  37. for (int i = 0; i <= 1; i++)
  38. {
  39. t[father].mi_n[i] = min(t[father].mi_n[i], t[son].mi_n[i]);
  40. t[father].ma_x[i] = max(t[father].ma_x[i], t[son].ma_x[i]);
  41. }
  42. }
  43. void up_data(int rt)
  44. {
  45. int l = t[rt].l, r = t[rt].r;
  46. if (l)
  47. gengxin(rt, l);
  48. if (r)
  49. gengxin(rt, r);
  50. }
  51. int build(int begin, int end, int fx)
  52. {
  53. int m = (begin + end) >> 1;
  54. now = fx;
  55. nth_element(t + begin, t + m, t + end + 1, cmp_1);
  56. for (int i = 0; i <= 1; i++)
  57. t[m].mi_n[i] = t[m].ma_x[i] = t[m].d[i];
  58. t[m].sie = end - begin + 1;
  59. if (begin < m) t[m].l = build(begin, m - 1, 1 - fx); else t[m].l = 0;
  60. if (m < end) t[m].r = build(m + 1, end,1 - fx);else t[m].r = 0;
  61. up_data(m);
  62. return m;
  63. }
  64. LL query(int rt, point a)
  65. {
  66. if (!rt) return 0;
  67. int ju = 0;
  68. ju += pd(t[rt].mi_n[0], t[rt].mi_n[1], a);
  69. ju += pd(t[rt].mi_n[0], t[rt].ma_x[1], a);
  70. ju += pd(t[rt].ma_x[0], t[rt].mi_n[1], a);
  71. ju += pd(t[rt].ma_x[0], t[rt].ma_x[1], a);
  72. if (ju == 4)
  73. return t[rt].sie;
  74. if (ju == 0)
  75. return 0;
  76. ju = pd(t[rt].d[0], t[rt].d[1], a);
  77. return ju + query(t[rt].l, a) + query(t[rt].r, a);
  78. }
  79. int main()
  80. {
  81. //freopen("F:\\rush.txt", "r", stdin);
  82. int T;
  83. rei(T);
  84. while (T--)
  85. {
  86. LL ans = 0;
  87. rei(n);
  88. rep1(i, 1, n)
  89. rel(a[i]);
  90. LL l = n / 2;
  91. rep1(i, 0, (1 << l) - 1)
  92. {
  93. LL sum = 0, sqrsum = 0;
  94. rep1(j,1,l)
  95. if (i&(1 << (j - 1)))
  96. sum += a[j], sqrsum += a[j] * a[j];
  97. t[i + 1].d[0] = sum, t[i + 1].d[1] = (sum*sum - sqrsum) / 2;
  98. }
  99. root = build(1, 1 << l, 0);
  100. l = n - l;
  101. rep1(i, 0, (1 << l) - 1)
  102. {
  103. LL sum = 0, sqrsum = 0;
  104. rep1(j, n / 2 + 1, n)
  105. if (i&(1 << (j - n / 2 - 1)))
  106. sum += a[j], sqrsum+=a[j] * a[j];
  107. point t;
  108. t.d[0] = sum, t.d[1] = (sum*sum - sqrsum) / 2;
  109. ans += query(root, t);
  110. }
  111. printf("%lld\n", ans-1);
  112. }
  113. //printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
  114. return 0;
  115. }

【BestCoder Round #93 1004】MG loves set的更多相关文章

  1. 【BestCoder Round #93 1001】MG loves gold

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=6019 [题意] 每次选择一段连续的段,使得这一段里面没有重复的元素; 问你最少选多少次; [题解] ...

  2. 【BestCoder Round #93 1002】MG loves apple

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=6020 [题意] 给你一个长度为n的数字,然后让你删掉k个数字,问你有没有删数方案使得剩下的N-K个 ...

  3. [HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP)

    [HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP) 题面 有三个人从一张N个点无重边的有向无环图上的三个点出发,每单位时间,他们分别选择当前 ...

  4. 【HDU 6021】 MG loves string (枚举+容斥原理)

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

  5. 【HDU 6020】 MG loves apple (乱搞?)

    MG loves apple  Accepts: 20  Submissions: 693  Time Limit: 3000/1500 MS (Java/Others)  Memory Limit: ...

  6. 【玲珑杯 round#18 B】图论你先敲完模板

    [Link]:http://www.ifrog.cc/acm/problem/1146 [Description] [Solution] 设f[i]表示在第i个点休息的话最少需要的体力值; f[i]= ...

  7. 【CS Round #43 E】Coprime Pairs

    [链接]点击打开链接 [题意] 让你选择n个数字,组成一个数组,使得这n个数字中恰好有k对,它们是互质的. [题解] 我们可以先找出前n个质数,那么接下来的问题就转化为,凑出rest = n*(n-1 ...

  8. 【CS Round #43 D】Bad Triplet

    [链接]点击打开链接 [题意] 给你n个点m条边的无权无向联通图; 让你找3个点A,B,C 使得A->B=B->C=A->C 这里X->Y表示点X到点Y的最短路长度. [题解] ...

  9. 【CS Round #43 C】Rectangle Partition

    [链接]点击打开链接 [题意] 有一辆火车,它的长度为L,然后假设这辆车现在随机可能地出现在0..D之间,然后假设它已经耗光了油. 问你它需要走的期望距离是多少. 这里要走的距离指的是车里最近的加油站 ...

随机推荐

  1. vuecli3取消eslint

    1.之前好好的项目,今天运行npm run serve.忽然报错运行不了了. 2.原因 在生成项目时候没有忽略 ESlint选项配置,其实建议创建项目的时候还是忽略掉这个选项比较好,因为后期写项目多空 ...

  2. OSGi教程:Class Space Consistency

    此教程基于OSGi Core Release 7 OSGi类空间的一致性 详细内容上面英文教程有详细解答 下面主要是一些个人见解,若有不当之处,欢迎指出: "Class space cons ...

  3. LintCode_46 主元素

    题目 给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一. 样例 给出数组[1,1,1,1,2,2,2],返回 1 思路 首先 发现所给的数组是顺序排列好的. 用动态规划 ...

  4. Android 程序员不得不收藏的个人博客(持续更新...)

    本文已收录我的 Github ,持续更新中 ,欢迎点赞 ! 每周打开一次收藏夹里的个人博客,已经成为了我的人生一大乐趣. 相比各大博客平台,我一直更加偏爱个人博客.在每个人自己的这一亩三分地里,你能看 ...

  5. 蚁群算法MATLAB解VRP问题

    Excel  exp12_3_2.xls内容: ANT_VRP函数: function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ANT ...

  6. 第三方数据库管理工具Navicat使用教程

    一.Navicat Premium是一个功能强大的第三方数据库管理工具,可以连接管理MySQL.Oracle.PostgreSQL.SQLite 及 SQL Server数据库. 使用Navicat软 ...

  7. Amazon Redshift数据迁移到MaxCompute

    Amazon Redshift数据迁移到MaxCompute Amazon Redshift 中的数据迁移到MaxCompute中经常需要先卸载到S3中,再到阿里云对象存储OSS中,大数据计算服务Ma ...

  8. Python 中的 map, reduce, zip, filter, lambda基本使用方法

    map(function, sequence[, sequence, ...] 该函数是对sequence中的每个成员调用一次function函数,如果参数有多个,则对每个sequence中对应的元素 ...

  9. 几种常见的flex布局

    1,水平等距排列.俩端对齐.垂直方向居顶对齐 html: <div class="container flex"> <div class="div1&q ...

  10. day002--python编程的相关软件,变量

    --python是一门解释型语言,需要安装解释器,由于python3和python不兼容,所以需要安装这两个版本的解释器. 目前python2.7版本已经停止更新,使用企业较少,所以应当以学习pyth ...