首页 > 其他分享 >可持久化线段树

可持久化线段树

时间:2022-11-11 09:11:11浏览次数:47  
标签:持久 int 线段 kmax quad include tc

可持久化线段树

可持久化权值线段树

· 又叫主席树

· 本质就是多棵线段树

· 可持久化表示可以维护历史任一版本的数据

· 例题

\(\quad\) · Q1:给定 \(n\) 个整数构成的序列 ,需要支持两种操作

\(\quad\quad\) · 在某个历史版本上修改某一个位置上的值

\(\quad\quad\) · 访问某个历史版本上的某一位置的值

\(\quad\) · A1: 保存每次插入操作时的历史版本.

\(\quad\quad\) · 对于每次操作都开一棵线段树

\(\quad\quad\) · 空间显然会爆,考虑优化

\(\quad\quad\) · 可以观察到,对于每次修改操作,最多更改 \(O(\log n)\) 个节点(单点修改最多遍历 \(O(\log n)\) 个节点)

\(\quad\quad\) · 因此对于每次修改,动态开点记录修改的状态。这样可以大大地减少冗余

\(\quad\quad\) · 注意存树一定要动态开点!!!

\(\quad\) · Code:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int kmax = 1e6 + 3;

int n, m, a[kmax];
int rt[kmax];

struct Segment {
  struct Tree {
    int l, r, mid, s;
    int ls, rs;     //记录左右儿子
  } t[kmax << 5];
  int tc;

  Segment() {
    tc = 0;
  }

  int Build(int x, int l, int r) {
    t[x] = {l, r, (l + r) >> 1};
    if (l == r) {
      t[x].s = a[l];
      return x;
    }
    t[x].s = 0;
    t[x].ls = Build(++tc, l, t[x].mid);    //动态开点储存节点
    t[x].rs = Build(++tc, t[x].mid + 1, r);
    return x;
  }

  int Modify(int x, int k, int v) {
    t[++tc] = t[x];     //记录新版本
    x = tc;
    if (t[x].l == k && k == t[x].r) {
      t[x].s = v;
      return x;
    }
    if (k <= t[x].mid) {
      t[x].ls = Modify(t[x].ls, k, v);
    } else {
      t[x].rs = Modify(t[x].rs, k, v);
    }
    return x;
  }

  int Query(int x, int k) {
    if (t[x].l == t[x].r && t[x].l == k) {
      return t[x].s;
    }
    if (k <= t[x].mid) return Query(t[x].ls, k);
    return Query(t[x].rs, k);
  }

} tr;

int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  rt[0] = tr.Build(++tr.tc, 1, n);
  for (int i = 1, tim, op, x, v; i <= m; i++) {
    scanf("%d%d%d", &tim, &op, &x);
    if (op == 1) {
      scanf("%d", &v);
      rt[i] = tr.Modify(rt[tim], x, v);
    } else {
      printf("%d\n", tr.Query(rt[tim], x));
      rt[i] = rt[tim];
    }
  }
  return 0;
}

标签:持久,int,线段,kmax,quad,include,tc
From: https://www.cnblogs.com/ereoth/p/16879506.html

相关文章