线段树测试

1|0线段树所思所记

线段树是一种 维护区间信息 的数据结构,在 O(log n) 的时间复杂度内实现 单点修改、区间修改、单点查询,区间查询(区间求和,求区间最大值,求区间最小值) 等操作。

  • 1|1代码

    #include<iostream> using namespace std; namespace SegmentTree { static unsigned lim; static unsigned* a; using cints = const unsigned&; constexpr unsigned maxn = 1e5; enum class ArrayState { UnSet, AllZero, AllOne }; struct node { struct son { static inline unsigned lft(cints root) { return root << 1; } static inline unsigned rit(cints root) { return root << 1 | 1; } }; struct tags { template<node* seg> static inline void pushdown(cints root, cints l, cints r) { if (seg[root].tag.state == ArrayState::UnSet) return; const auto lc = son::lft(root), rc = son::rit(root), mid = midof(l,r); seg[lc].tag.state = seg[rc].tag.state = seg[root].tag.state; if (seg[root].tag.state == ArrayState::AllOne) { seg[lc].val.cnt = mid - l + 1; seg[rc].val.cnt = r - mid; } else seg[lc].val.cnt = seg[rc].val.cnt = 0; seg[root].tag.state = ArrayState::UnSet; } ArrayState state; }tag; struct vals { unsigned cnt; template<node* seg> static inline void update(cints root) { seg[root].val.cnt = seg[son::lft(root)].val.cnt + seg[son::rit(root)].val.cnt; } }val; static inline void tie(unsigned* Arr) { a = Arr; } static inline const unsigned midof(cints l, cints r) { return ((r - l) >> 1) + l; } template<node* seg> static void build(cints root, cints l, cints r) { if (l == r) return void(seg[root].val.cnt = (a[l] >= lim)); node::build<seg>(son::lft(root), l, midof(l, r)), node::build<seg>(son::rit(root), midof(l, r) + 1, r); vals::update<seg>(root); seg[root].tag.state = ArrayState::UnSet; } struct gets { template<node* seg> static unsigned cntof(cints root, cints ml, cints mr, cints ql, cints qr) { if (ql <= ml && mr <= qr) return seg[root].val.cnt; if (ql > mr || qr < ml) return 0; tags::pushdown<seg>(root, ml, mr); return gets::cntof<seg>(son::lft(root), ml, midof(ml, mr), ql, qr) + gets::cntof<seg>(son::rit(root), midof(ml, mr) + 1, mr, ql, qr); } template<node* seg> static const vals pointof(cints root, cints l, cints r, cints on){ if (l == on && r == on) return seg[root].val; tags::pushdown<seg>(root, l, r); if (auto mid = midof(l, r); on <= mid) return gets::pointof<seg>(son::lft(root), l, mid, on); else return gets::pointof<seg>(son::rit(root), mid + 1, r, on); } }; struct update { template<node* seg> static inline void sets(cints root, cints ml, cints mr, cints ql, cints qr, cints val){ if (ql <= ml && qr >= mr) return void(seg[root].val.cnt = val * (mr - ml + 1)), void(seg[root].tag.state = (val ? ArrayState::AllOne : ArrayState::AllZero)); if (ql > mr || qr < ml) return; tags::pushdown<seg>(root, ml, mr); update::sets<seg>(son::lft(root), ml, midof(ml,mr), ql, qr, val); update::sets<seg>(son::rit(root), midof(ml, mr) + 1, mr, ql, qr, val); vals::update<seg>(root); } }; } nnd[maxn]; } unsigned a[SegmentTree::maxn],L[SegmentTree::maxn],R[SegmentTree::maxn],p,n,m; char opt[SegmentTree::maxn]; template<SegmentTree::node* seg> inline const bool check(const unsigned int& x){ SegmentTree::lim = x; SegmentTree::node::build<seg>(1, 1, n); for (unsigned i = 1; i <= m; ++i) if (unsigned cnt1 = SegmentTree::node::gets::cntof<seg>(1, 1, n, L[i], R[i]);opt[i] == '0') SegmentTree::node::update::sets<seg>(1, 1, n, R[i] - cnt1 + 1, R[i], 1), SegmentTree::node::update::sets<seg>(1, 1, n, L[i], R[i] - cnt1, 0); else SegmentTree::node::update::sets<seg>(1, 1, n, L[i], L[i] + cnt1 - 1, 1), SegmentTree::node::update::sets<seg>(1, 1, n, L[i] + cnt1, R[i], 0); return SegmentTree::node::gets::pointof<seg>(1, 1, n, p).cnt; } int main() { ios::sync_with_stdio(0), cin.tie(0), std::cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) cin>>a[i]; SegmentTree::node::tie(a); for (int i = 1; i <= m; i++) { cin>>opt[i]>>L[i]>>R[i]; } cin>>p; int ll = 1, rr = n, midd, ans=0; while (ll <= rr) if(midd = (ll + rr) >> 1;check<SegmentTree::nnd>(midd)) ans = midd, ll = midd + 1; else rr = midd - 1; std::cout << ans; return 0; }
  • 1|2铺垫

    因为线段树特性,定义了 struct son

    static unsigned lim; static unsigned* a; using cints = const unsigned&; constexpr unsigned maxn = 1e5; enum class ArrayState { UnSet, AllZero, AllOne }; struct node { struct son { static inline unsigned lft(cints root) { return root << 1; } static inline unsigned rit(cints root) { return root << 1 | 1; } }; }
  • 1|3构建


__EOF__

本文作者Orlicz
本文链接https://www.cnblogs.com/Orlicz/p/16580260.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Orlicz  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示