Bitset([HZOI 2015]偏序++)
2018-01-07 20:09
465 查看
Bitset简介
下面介绍C++ STL 中一个非常有用的东西:Bitset
类似于二进制状压,它可以把信息转化成一个01串存储起来
定义方法:
首先要
#include<bitset>或#include<bits/stdc++.h>
然后定义一个长度为len的bitset S
bitset<len>S;
一些操作
bitset还支持&,^,|三个运算
b._Find_first() 找到第一个1的位置
b._Find_next(x)找到x后面为1的第一个位置
复杂度
时间:我感觉很慢,但学长说是O(玄学),而且开了氧气优化后跑的飞快空间:自己测一下就好
[HZOI 2015]偏序++
题面戳我这是一道有趣的k+1维偏序,加上下标最多有7维
树套树套树套......套树?显然写不出
几层CDQ套在一起?O(n log^k n),TLE飞了
kd-tree可以卡过
这道题可以考虑用bitset做
对于每一个k+1维的组合,如果求出每一维小于它的集合,答案就是每一维的交集,就是二进制按位与
用bitset可以做到
可以这样
bitset <40000> S[8][40000]
然后就AC了
???等等,你当bitset不要空间的吗?显然不行
所以我们考虑分块,只记录下每块块顶的,快内的暴力算,时间O(\(n\sqrt n\))
可以吊打kd-tree
代码
# include <bits/stdc++.h> # define IL inline # define RG register # define Fill(a, b) memset(a, b, sizeof(a)) # define Copy(a, b) memcpy(a, b, sizeof(a)) # define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout) using namespace std; typedef long long ll; const int _(5e4 + 10); IL ll Read(){ RG char c = getchar(); RG ll x = 0, z = 1; for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); return x * z; } int n, bl[_], pre[_], suf[_], blo, k, b[8][_], bblo; pair <int, int> a[8][_]; bitset <_> S[8][250]; IL int Find(RG int v, RG int x){ RG int l = 1, r = n, ans = 0; while(l <= r){ RG int mid = (l + r) >> 1; if(a[x][mid].first <= v) l = mid + 1, ans = mid; else r = mid - 1; } return ans; } IL bitset <_> Getbst(RG int x, RG int y){ bitset <_> ans; ans.reset(); RG int pos = Find(y, x); if(!pos) return ans; ans = S[x][bl[pos] - 1]; for(RG int i = pre[pos]; i <= pos; ++i) ans.set(a[x][i].second); return ans; } IL ll Calc(){ bitset <_> ans; RG ll ret = 0; for(RG int i = 1; i <= n; ++i){ ans.set(); for(RG int j = 1; j <= k; ++j) ans &= Getbst(j, b[j][i]); ret += ans.count() - 1; } return ret; } int main(RG int argc, RG char* argv[]){ File("partial_order_plus"); n = Read(); k = Read() + 1; bblo = sqrt(n); for(RG int i = 1; i <= n; ++i) a[1][i] = make_pair(b[1][i] = i, i); for(RG int j = 2; j <= k; ++j) for(RG int i = 1; i <= n; ++i) a[j][i] = make_pair(b[j][i] = Read(), i); for(RG int i = 1; i <= n; ++i){ bl[i] = (i - 1) / bblo + 1; pre[i] = (bl[i] - 1) * bblo + 1; suf[i] = min(n, bl[i] * bblo); } blo = bl ; for(RG int i = 2; i <= k; ++i) sort(a[i] + 1, a[i] + n + 1); for(RG int j = 1; j <= k; ++j) for(RG int i = 1; i <= blo; ++i){ S[j][i] = S[j][i - 1]; RG int d = (i - 1) * bblo + 1; for(RG int l = pre[d]; l <= suf[d]; ++l) S[j][i].set(a[j][l].second); } printf("%lld\n", Calc()); return 0; }
相关文章推荐
- COGS 2580. [HZOI 2015]偏序 II (CDQ分治+BIT)
- COGS 2580. [HZOI 2015]偏序 II
- COGS2580:[HZOI 2015]偏序 II (三层CDQ分治+树状数组)
- 2015北京网络赛 J Clarke and puzzle 求五维偏序 分块+bitset
- [五维偏序 分块 bitset] HihoCoder #1236 2015北京网络赛 J Scores
- COGS-2282 [HZOI 2015]黑树白(树状数组+树链剖分)
- COGS2287 [HZOI 2015]疯狂的机器人
- 【2015广东工业大学新生赛E】【c++函数 bitset读入二进制转十进制数】GDUT的实验室 十进制与二进制的比较
- 【整理】STL中的bitset(二进制华丽解决假五维偏序题)
- [COGS2479 && COGS2639]高维偏序(CDQ分治,bitset)
- BZOJ4484 JSOI2015最小表示(拓扑排序+bitset)
- XJOI NOIP2015模拟赛Day1 T2 ctps bitset优化 或 排序+cdq分治+树状数组+平衡树
- cogs 2123. [HZOI 2015] Glass Beads
- cogs 2287. [HZOI 2015]疯狂的机器人 (NTT优化DP)
- 【COGS2479】 HZOI2016—偏序
- 2015 Multi-University Training Contest 10 (hdu 5406-5416)数据结构+dp+矩阵快速幂+bitset优化拓扑排序+(dp&树状数组)
- hihocoder1236(2015长春网赛J题) Scores(bitset && 分块)
- CIA11 毒瘤题(七维偏序,分块+bitset)
- [COGS 2258][HZOI 2015]复仇的序幕曲
- COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]