bitset求解高维偏序

bitset求解高维偏序

今天模拟赛不想打了,于是在赛时最后几个小时看的这个。

  • bitset的基础用法

简单介绍几个成员函数

  1. set()/set(pos) : 将所有位/第pos位赋值为true,时间复杂度O(nw)/O(1)
  2. reset()/reset(pos) : 将所有位/第pos位赋值为false,时间复杂度O(nw)/O(1)
  3. filp()/filp(pos) : 将所有位/第pos取反,时间复杂度同上
  4. & / | / << / >> 等运算符,时间复杂度O(nw)
  5. count() : 统计为1的个数,复杂度O(1)

求解高维偏序的话就用这几个(没有全用上),其它的函数可以看另一篇博客虽然还没有写但马上就会补

【模板】三维偏序(陌上花开)为例

其实求解高维偏序就是求|j=1k{x|aj,xai,x}|,这个直接用bitset求并集即可。

n个 bitset,bi,j=1表示j每一维的数值都不超过i。初始化所有bi,j=1

枚举维度,将所有数按照维度排序

开一个新的 bitset s,按这一维从小到大处理所有数,处理到isj=1表示当前维j不超过 i

因为j是单调的,用一个指针维护即可。

最后bis取并集即可

发现开nn维bitset空间会寄,于是考虑分块处理,复杂度不变

预处理的话复杂度确实不变,但是因为难写所以这篇代码是O(n3kbw),但是因为b开的很大加上常数小所以一样可过

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
// FILE *ErrFile=errfile("err.err");
#else
FILE *Infile = stdin,*OutFile = stdout;
//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 1e5 + 10;
int n,emm,ans[N],a[4][N],p[4][N];
bitset<N> vis[9999];
inline void solve(){
cin>>n>>emm;
for(int i = 1;i <= n; ++i)
cin>>a[1][i]>>a[2][i]>>a[3][i],p[1][i] = p[2][i] = p[3][i] = i;
for(int i = 1;i <= 3; ++i){
sort(p[i] + 1,p[i] + 1 + n,[=](int x,int y){return a[i][x] < a[i][y];});
}
for(int l = 1,r;l <= n; l = r + 1){
r = min(l + 9990,n);
for(int i = l;i <= r; ++i) vis[i-l].set();
for(int i = 1;i <= 3; ++i){
bitset<N> s;s.reset();
for(int j = 1,k = 1;j <= n; ++j){
int now = p[i][j];
for(;k <= n && a[i][p[i][k]] <= a[i][now];) s[p[i][k++]] = true;
if(l <= now && now <= r) vis[now - l] &= s;
}
}
for(int i = l;i <= r; ++i) ++ans[vis[i-l].count()];
}
for(int i = 1;i <= n; ++i) cout<<ans[i]<<'\n';
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
solve();
}

啥,你说要多维?改个数就好了呀!

upd : 其实预处理也不难写,就是分块写法,bi,j表示前i块j维的状态,时间复杂度没变,但貌似加了一个O(b)的常数?

但是非常难调,然后我没写出来……

posted @   CuFeO4  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示