若干道偏序问题(STL,分块)

找了4道题目

BZOJ陌上花开(权限题,提供洛谷链接)

Cogs2479偏序

Cogs2580偏序II

Cogs2639偏序++


作为一个正常人,肯定先看三维偏序

做法很多呀

首先,由于

智商不够数据结构来补 $ \ \ \ \ \ \ $--菊开

所以我们用最傻逼的数据结构来做这道题目

第一维:排序

第二维:树状数组

第三维:平衡树

于是乎,我们得到了一个复杂度为\(O(nlog^2n)\)的做法

并且常数巨大

这个做法到这里去看



第二种做法
CDQ分治
相信大家都会逆序对的求法
可以归并排序求逆序对
逆序对相当于是一个二维偏序
第一维就相当于它的位置
第二维就是值
每次归并排序的时候相当于分成了两部分
只有左侧的部分才能对右侧的部分产生贡献

这里同理,第一维排序

第二维类似于归并排序就行合并

同时一遍归并一边计算第三维

是不是想到了逆序对还可以用树状数组来求

所以这里一样的,

第三维用一个BIT来求就行了

这种做法看这里

恩,三维偏序没了


现在看Cogs的【偏序】

四维偏序模板题

可以顺着三维偏序来思考

既然多了一维

我就多套个CDQ分治呀

那不就是CDQ分治套树套树

或者CDQ分治套CDQ分治加树状数组

复杂度\(O(nlog^3n)\)

好像也可以诶。。。


好好好

我们继续

Cogs【偏序II】

不就是个五维偏序吗

CDQ套CDQ套CDQ

或者CDQ套CDQ套树套树

没毛病,时间复杂度\(O(nlog^4n)\)

可以做可以做,没问题的


那,我们继续

Cogs【偏序++】

七维偏序呀

CDQ套CDQ套CDQ套CDQ套CDQ

或者CDQ套CDQ套CDQ套CDQ套树套树

时间复杂度\(O(nlog^6n)\)

绝对跑不过的

而且给定的维数是K

你还得分类讨论,看着就是不可做的题目呀。。。

怎么办怎么办。。。


首先,请允许我orz大佬 ——中国翅王

这是他的PPT


FHR的做法的复杂度:\(O(n\sqrt n)\)

首先,我们知道

一个向量的偏序数量

等于它每一维的偏序数量的交集的大小

所以,按照每一维排序之后

我们就可以求出比每一维小的集合

然后求一个交集就行了

但是,暴力求,,,不现实吧。

而且交集也不好求呀

所以,来搞个\(bitset\)

STL大法好

但是,这样不就是\(O(n^2)\)的暴力吗???

没错,我们再来一发——分块大法好

分块之后就可以把一个\(n\)变成\(\sqrt n\)

于是复杂度就降到了\(O(n \sqrt n)\)

美滋滋

献上丑陋的代码(【偏序++】)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<bitset>
  11. #include<queue>
  12. using namespace std;
  13. #define MAX 45000
  14. inline int read()
  15. {
  16. int x=0,t=1;char ch=getchar();
  17. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  18. if(ch=='-')t=-1,ch=getchar();
  19. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  20. return x*t;
  21. }
  22. int n,blk;
  23. bitset<45000> bs[15][250];
  24. pair<int,int> val[15][MAX];
  25. int bl[MAX],bll[MAX],blr[MAX];
  26. int K,num;
  27. long long Ans;
  28. int f[15][MAX];
  29. int find(int k,int x)
  30. {
  31. int l=1,r=n,ans=0;
  32. while(l<=r)
  33. {
  34. int mid=(l+r)>>1;
  35. if(val[k][mid].first<=x)ans=x,l=mid+1;
  36. else r=mid-1;
  37. }
  38. return ans;
  39. }
  40. inline bitset<MAX> getbst(int p,int x)
  41. {
  42. bitset<MAX> ans;ans.reset();
  43. int pp=find(p,x);
  44. if(pp<=0)return ans;
  45. int pre=(pp-1)/blk;
  46. int st=pre*blk+1;
  47. ans=bs[p][pre];
  48. for(int i=st;i<=pp;++i)ans.set(val[p][i].second);
  49. return ans;
  50. }
  51. void Solve()
  52. {
  53. bitset<MAX> ans;ans.reset();
  54. for(int i=1;i<=n;++i)
  55. {
  56. ans.set();
  57. for(int j=1;j<=K;++j)
  58. ans&=getbst(j,f[j][i]);
  59. Ans+=ans.count()-1;
  60. }
  61. }
  62. int main()
  63. {
  64. freopen("partial_order_plus.in","r",stdin);
  65. freopen("partial_order_plus.out","w",stdout);
  66. n=read();blk=sqrt(n);K=read()+1;
  67. for(int i=1;i<=n;++i)val[1][i]=make_pair(f[1][i]=i,i);
  68. for(int j=2;j<=K;++j)
  69. for(int i=1;i<=n;++i)
  70. val[j][i]=make_pair(f[j][i]=read(),i);
  71. for(int i=1;i<=K;++i)sort(&val[i][1],&val[i][n+1]);
  72. for(int i=1;i<=n;++i)
  73. bl[i]=(i-1)/blk+1;num=bl[n];
  74. for(int i=1;i<=num;++i)
  75. bll[i]=(i-1)*blk+1,blr[i]=i*blk;blr[num]=n;
  76. for(int j=1;j<=K;++j)
  77. for(int i=1;i<=num;++i)
  78. {
  79. bs[j][i]=bs[j][i-1];
  80. for(int k=bll[i];k<=blr[i];++k)
  81. bs[j][i][val[j][k].second]=1;
  82. }
  83. Solve();
  84. printf("%lld\n",Ans);
  85. return 0;
  86. }

几道很Interesting的偏序问题的更多相关文章

  1. 两道很好的dp题目【4.29考试】

    A 问题描述: 对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用I表示,反之这个位置是下降的,用D表示.如排列3,1,2,7,4,6,5可以表示为DIIDID. 现 ...

  2. 【学习笔记】使用 bitset 求解较高维偏序问题

    求解五维偏序 给定 \(n(\le 3\times 10^4)\) 个五元组,对于每个五元组 \((a_i, b_i, c_i, d_i, e_i)\),求存在多少个 \(1\le j\le n\) ...

  3. 高斯消元几道入门题总结POJ1222&&POJ1681&&POJ1830&&POJ2065&&POJ3185

    最近在搞高斯消元,反正这些题要么是我击败了它们,要么就是这些题把我给击败了.现在高斯消元专题部分还有很多题,先把几道很简单的入门题总结一下吧. 专题:http://acm.hust.edu.cn/vj ...

  4. 我也不知道什么是"莫比乌斯反演"和"杜教筛"

    我也不知道什么是"莫比乌斯反演"和"杜教筛" Part0 最近一直在搞这些东西 做了将近超过20道题目吧 也算是有感而发 写点东西记录一下自己的感受 如果您真的 ...

  5. Codeforces Round #415 (Div. 2) 翻车啦

    A. Straight «A» time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. ZOJ Problem Set - 1006 Do the Untwist

    今天在ZOJ上做了道很简单的题目是关于加密解密问题的,此题的关键点就在于求余的逆运算: 比如假设都是正整数 A=(B-C)%D 则 B - C = D*n + A 其中 A < D 移项 B = ...

  7. wex5 实战 单页模式下的多页面数据同步

    在wex5官方教程中,关于多页模式与单页模式进行了对比.两者最大的区别在于: 1 web加载速度,单页模式快于多页模式 2  多页模式对加载机制进行了预加载,一次加载之后再次加载,就会加快. 但是,由 ...

  8. 【BZOJ-3306】树 线段树 + DFS序

    3306: 树 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 792  Solved: 262[Submit][Status][Discuss] De ...

  9. hdu Remainder

    这道题是道很明显的bfs题.因为对数论没什么研究 ,所以这道题目里的两个关键点并不知道,看了别人的题解才知道 . 1.为避免取模后出现负数,采用:x%y=(x%y+y)%y 2.全部采用对m*k取模后 ...

随机推荐

  1. 网络服务器操作命令telnet

    有些命令是内部的,系统自带的,在装好系统后,就可以随时使用有些命令是系统中没有的,要自己安装一下才能使用,比如你说的telnet,需要安装一下才能使用的.CentOS中用 yum install te ...

  2. Gentoo(贱兔)Linux安装笔记

      网上对于Gentoo Linux 的教程少之又少,所以这里我将自己的安装记录贴出来 希望对正在研究Gentoo 的小伙伴们有帮助! 1.确认连接到互联网,使用net-setup工具配置网络 roo ...

  3. HashMap中的散列函数、冲突解决机制和rehash

    一.概述 散列算法有两个主要的实现方式:开散列和闭散列,HashMap采用开散列实现. HashMap中,键值对(key-value)在内部是以Entry(HashMap中的静态内部类)实例的方式存储 ...

  4. linux、windows系统间传输文件

    日常工作中经常涉及到系统间的文件传输,下面就简单说一下常用的方法   linux--windows      工具:winscp.SecureCRT.Zmodem(sz, rz)   linux--l ...

  5. Linux 每日命令行

    uptime 用于查看系统的负载信息. 它依次显示 当前系统时间.系统已运行时间.启用终端数量及平均负载值等信息.平均负载指的是系统在最近1分钟.5分钟.15分钟内的压力情况:负载值越低越好,尽量不要 ...

  6. 正本清源区块链——Caoz

    正本清源区块链 说明:以下内容整理自Caoz的<正本清源区块链>,如有不妥,请联系我修改或删除. 简介 不讨论炒币!不讨论炒币!不讨论炒币! 本课程内容分为两部分: 第一部分,烧脑篇,介绍 ...

  7. angular4升级angular5问题记录之this.location.back()

    在之前的项目中,导航回上一个路由采用注入的Location服务,利用浏览器的历史堆栈,导航到上一步. 官方文档也就是这么写的 而然在升级到5.2的版本的时候,在浏览器运行的时候并没有什么问题,在项目打 ...

  8. the c programing language 学习过程7

    interact 互动 carriage运费运输 linefeed 换行 redirection改方向 interleaved交叉存取 adequate足够的 untouched原样的  specif ...

  9. kubernetes 单节点和多节点环境搭建

    kubernetes单节点环境搭建: 1.在VMWare Workstation中建立一个centos 7虚拟机.虚拟机的配置尽量调大一些 2.操作系统安装完成后,关闭centos 自带的防火墙服务 ...

  10. JavaScript基础教程1-20160612

    1.javascript是一门浏览器运行的脚本语言和java没关系 2.javascript语言写在哪里? (1)可以写单独的文件里面去调用(推荐采用此方法) index.html <head& ...