书接上回

一维偏序直接做、二维偏序套线段树或归并排序、三维偏序可以树套树或者 CDQ 套树,那四维偏序呢?可以 CDQ 套树套树。那五维偏序呢?可以发现,无论是 CDQ 分治还是树,都很难再继续嵌套,再写下去不但码量巨大,还巨难调,效率还相当低。树或 CDQ 嵌套 \(m\) 维偏序时间复杂度为 \(O(n\log^{m-1}n)\)。但是,我们使用 STL 的 bitset 可以在 \(O(\tfrac{n^2m}{w})\) 的优秀复杂度内解决这个问题。

前置知识:

bitset 的基本用法

最直观的做法是对每个维度开个 \(n\times m\) 的 \(01\) 矩阵,\(a_{i,j}\) 为 \(1\) 表示,在这个维度下 \(a_{i}\le a_{j}\),反之则是 \(a_{i}\gt a_{j}\)。如果我们要求每个维度都比 \(i\) 小的点的数量,直接把这 \(m\) 个维度的 \(01\) 矩阵的第 \(i\) 行与一下求 \(1\) 的个数就行了。

开 \(mn^2\) 的数组,bitset 也很难开的下,注意到单独的数组是没用的,所以在对每一维统计时直接与上之前的答案。对每一维排序,然后从小到大遍历物品,开一个临时 bitset 来存只考虑该维,值比当前位置小的位置,类似前缀的维护方法。注意初始化。排序时注意直接交换数组是 \(O(m)\) 的,所以只能对下标排序。一定要注意是 \(\le\) 还是 \(\lt\)。相当好写。

推个板子题

这题直接 bitset 预处理 \(m\) 维偏序,然后跑个相当显然的 \(O(n^2)\) dp 即可。注意为了保证只能从前面转移,dp 前按任意一维排个序,避免漏掉情况。比较卡常,写写快读快写。

教授の代码
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define inf 0x3f3f3f3f
namespace inout
{
#define super faster
#ifdef super
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif
template<typename tn> il void read(tn &x)
{
x=0;
register bool op=false;
register char ch=getchar();
while(ch<'0'||ch>'9')
{
op|=(ch=='-');
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^'0');
ch=getchar();
}
if(op)
{
x=~x+1;
}
}
template<typename tn> void writen(tn x)
{
if(x)
{
writen(x/10);
putchar(x%10|'0');
}
}
template<typename tn> il void write(tn x)
{
if(!x)
{
putchar('0');
return;
}
if(x<0)
{
putchar('-');
x=~x+1;
}
writen(x);
}
}using namespace inout;
int a,b,c[5005],qwer,ap[5005],ac;
bitset<5005>can[5005],now;
long long dp[5005],ans;
struct node
{
int val[505];
}pit[5005];
il bool cmp(int x,int y)
{
return pit[x].val[qwer]<pit[y].val[qwer];
}
int main()
{
read(a);
read(b);
for(ri i=1;i<=b;i++)
{
read(c[i]);
pit[i].val[0]=i;
can[i].set();
ap[i]=i;
}
for(ri i=1;i<=a;i++)
{
for(ri j=1;j<=b;j++)
{
read(pit[j].val[i]);
}
}
for(ri i=1;i<=a;i++)
{
qwer=i;
sort(ap+1,ap+1+b,cmp);
now.reset();
ri bg=0;
for(ri j=1;j<=b;j++)
{
if(pit[ap[j]].val[i]!=pit[ap[bg]].val[i])
{
while(bg!=j)
{
now.set(pit[ap[bg]].val[0]);
bg++;
}
bg=j;
}
can[pit[ap[j]].val[0]]&=now;
}
}
for(ri i=1;i<=b;i++)
{
ri h=pit[ap[i]].val[0];
for(ri j=1;j<i;j++)
{
ri k=pit[ap[j]].val[0];
if(can[h][k])
{
dp[h]=max(dp[h],dp[k]);
}
}
dp[h]+=c[h];
ans=max(ans,dp[h]);
}
write(ans);
return 0;
}

别 D 了,CDQ 分治会不了一点。

鲜花:bitset求解高维偏序的更多相关文章

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

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

  2. [COGS2479 && COGS2639]高维偏序(CDQ分治,bitset)

    COGS2479:四维偏序. CDQ套CDQ CDQ:对a分治,对b排序,再对a打标记,然后执行CDQ2 CDQ2:对b分治,对c归并排序,对d树状数组. #include<cstdio> ...

  3. hihoCoder.1513.小Hi的烦恼(bitset 五维偏序)

    题目链接 五维偏序,对每一维维护bitset,表示哪儿为1(比它大),然后5个bitset与起来就能得到答案了. 具体实现可以用5*n个bitset,按排名搞个前缀和. 复杂度\(O(n^2/w)\) ...

  4. C++简单版BitSet求解大量数据是否存在莫个数

    #include <iostream> using namespace std; template<int N> class BitSet { public: BitSet() ...

  5. hiho#1513 : 小Hi的烦恼 五维偏序

    hiho#1513 : 小Hi的烦恼 五维偏序 链接 hiho 思路 高维偏序用bitset,复杂度\((\frac{n^2}{32})\) 代码 #include <bits/stdc++.h ...

  6. 浅谈CDQ分治与偏序问题

    初识CDQ分治 CDQ分治是一个好东西,一直听着dalao们说所以就去学了下. CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. ...

  7. 【2019.8.15 慈溪模拟赛 T2】组合数(binom)(卢卡斯定理+高维前缀和)

    卢卡斯定理 题目中说到\(p\)是质数. 而此时要求组合数向质数取模的结果,就可以用卢卡斯定理: \[C_x^y=C_{x\ div\ p}^{y\ div\ p}\cdot C_{x\ mod\ p ...

  8. HAOI2017 简要题解

    「HAOI2017」新型城市化 题意 有一个 \(n\) 个点的无向图,其中只有 \(m\) 对点之间没有连边,保证这张图可以被分为至多两个团. 对于 \(m\) 对未连边的点对,判断有哪些点对满足将 ...

  9. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  10. SVM(支持向量机)的一点理解

    最近有被问到SVM的问题,不懂装懂,羞愧不已.百度有很多深入浅出介绍SVM的文章,我就不赘述了,这里写一点自己肤浅的理解. SVM的核心思想是把求解低维空间上的高维分类器转化为求解高维函数空间上的线性 ...

随机推荐

  1. python 离线安装依赖

    步骤: 1. 访问 https://pypi.org/ 2. 搜索要下载的依赖 3. 下载tar.gz文件 4. 解压,再解压(第一次解压后的dist文件夹内tar文件需解压) 5. 解压后的文件夹内 ...

  2. the request was rejected because no multipart boundary was found

    报错: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.t ...

  3. JDK有用的新特性-Java Record

    目录 Java Record Record使用 Instance Methods 静态方法 Static Method Record 的构造方法 step1: 紧凑和定制构造方法 Record 与 与 ...

  4. 17 Python异常处理(捕获异常、抛出异常、自定义异常)

    本篇是 Python 系列教程第 17 篇,更多内容敬请访问我的 Python 合集 当我们编写代码时,可能会遇到各种各样的错误情况,比如除数为零.找不到文件.网络问题等等.为了优雅地处理这些问题,P ...

  5. mybatis springboot多数据源,根据使用的数据库不同,执行不同的sql语句

    springboot 多数据源配置就不说了,百度太多的用例, 这里只说下在多数据源下切换执行sql逻辑 1.xml sql嵌套,通过<if>标签来判断,用的是mybatis自己sql动态拼 ...

  6. SPIE独立出版。遥感征稿中--2024年遥感与数字地球国际学术会议(RSDE 2024)

    ​ [成都,遥感主题,稳定EI检索]2024年遥感与数字地球国际学术会议(RSDE 2024) 2024 International Conference on Remote Sensing and ...

  7. Azure 入门系列 (第五篇 Azure Storage)

    本系列 这个系列会介绍从 0 到 1 搭建一个 Web Application 的 Server. 间中还会带上一些真实开发常用的功能. 一共 6 篇 1. Virtual Machine (VM) ...

  8. 为了更好的 Flutter | 2021 第二季度开发者调研

    自 Flutter 2 发布以后,诸多振奋人心的开发特性 也随之解锁,从 加速应用开发 到 流畅地开发多平台应用 都已经有了长足的进步.我们也从社区收集到了不少大家关心的问题,并进行了 解答.毫无疑问 ...

  9. HeaderFile (1.2-1.6) 中 hct.h 使用教程

    下载 HeaderFile 1.2 HCT 是干什么的 辅助数据生成 主干框架 你需要包含必须的头文件 hct.h 此外,你需要实现如下函数: void create() 数据生成函数 void so ...

  10. 【赵渝强老师】Oracle的PGA与数据库连接建立的过程

    首先,我们来了解一下Oracle的内存结构,如下: 关于Oracle的内存结构,详情请查看:[赵强老师]Oracle数据库的内存结构 (一)PGA的组成结构 PGA主要由以下三部分组成: 私有SQL区 ...