经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C » 查看文章
HihoCoder#1513 : 小Hi的烦恼(五维数点 bitset 分块)
来源:cnblogs  作者:自为风月马前卒  时间:2018/10/11 9:26:54  对本文有异议

题意

题目链接

Sol

五位数点问题,写个cdq分治套cdq分治套cdq分治套cdq分析就完了 可以用bitset搞

对于每一科开\(n\)个bitset,其中\(b[i]\)表示的排名为\(1 - i\)的人是哪些

查询的时候把每科的bitset &起来就行了

复杂度\(k\frac{n^2}{32}\)

然后可以分块加速一下

注意这里在预处理有个关于势能分析的操作:如果块内元素较少的话,可以每次跑根号个,然后和前面的|起来,如果元素较多的话直接从1开始跑

复杂度:\(k\frac{n\sqrt(n)}{32}\)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 30001;
  4. inline int read() {
  5. int x = 0, f = 1; char c = getchar();
  6. while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
  7. while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  8. return x * f;
  9. }
  10. int N, a[5][MAXN], rak[5][MAXN], base = 1;
  11. bitset<MAXN> B[5][175];
  12. main() {
  13. N = read(); base = sqrt(N);
  14. for (int i = 1; i <= N; i++) for (int j = 0; j < 5; j++) a[j][i] = read(), rak[j][a[j][i]] = i;
  15. for (int j = 0; j < 5; j++)
  16. for (int i = 1; i * base <= N; i++)
  17. for(int k = 1; k <= i * base; k++) B[j][i].set(rak[j][k]);
  18. for (int i = 1; i <= N; i++) {
  19. bitset<MAXN> tmp, cal; tmp.set();
  20. for(int j = 0; j < 5; j++) {
  21. cal.reset();
  22. int now = a[j][i] / base;
  23. cal |= B[j][now];
  24. for(int k = now * base + 1; k <= a[j][i]; k++) cal.set(rak[j][k]);
  25. tmp &= cal;
  26. }
  27. printf("%d\n", tmp.count() - 1);
  28. }
  29. }
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号