鱼C论坛

 找回密码
 立即注册
查看: 2482|回复: 2

[技术交流] 线段树和树状数组的C++代码

[复制链接]
发表于 2014-4-15 09:48:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
线段树
  1. #ifndef SEGMENT_TREE
  2. #define SEGMENT_TREE

  3. #include <vector>

  4. class SegmentTree               // the segment tree is stored like a heap array
  5. {
  6.         std::vector<int> st, A;
  7.         int n;
  8.         int left (int p) { return p << 1; }       // same as binary heap operations
  9.         int right(int p) { return (p << 1) + 1; }

  10.         void build(int p, int L, int R)                               // O(n log n)
  11.         {
  12.                 if (L == R)                            // as L == R, either one is fine
  13.                         st[p] = L;                                       // store the index
  14.                 else {                                // recursively compute the values
  15.                         build(left(p) , L              , (L + R) / 2);
  16.                         build(right(p), (L + R) / 2 + 1, R          );
  17.                         int p1 = st[left(p)], p2 = st[right(p)];
  18.                         st[p] = (A[p1] <= A[p2]) ? p1 : p2;
  19.                 }
  20.         }

  21.         int rmq(int p, int L, int R, int i, int j)                      // O(log n)
  22.         {
  23.                 if (i >  R || j <  L) return -1; // current segment outside query range
  24.                 if (L >= i && R <= j) return st[p];               // inside query range

  25.                  // compute the min position in the left and right part of the interval
  26.                 int p1 = rmq(left(p) , L              , (L+R) / 2, i, j);
  27.                 int p2 = rmq(right(p), (L+R) / 2 + 1, R          , i, j);

  28.                 if (p1 == -1) return p2;   // if we try to access segment outside query
  29.                 if (p2 == -1) return p1;                               // same as above
  30.                 return (A[p1] <= A[p2]) ? p1 : p2;            // as as in build routine
  31.         }

  32.         int update_point(int p, int L, int R, int idx, int new_value)
  33.         {
  34.                 // this update code is still preliminary, i == j
  35.                 // must be able to update range in the future!
  36.                 int i = idx, j = idx;

  37.                 // if the current interval does not intersect
  38.                 // the update interval, return this st node value!
  39.                 if (i > R || j < L)
  40.                         return st[p];

  41.                 // if the current interval is included in the update range,
  42.                 // update that st[node]
  43.                 if (L == i && R == j) {
  44.                         A[i] = new_value; // update the underlying array
  45.                         return st[p] = L; // this index
  46.                 }

  47.                 // compute the minimum pition in the left and right part of the interval
  48.                 int p1, p2;
  49.                 p1 = update_point(left(p) , L              , (L + R) / 2, idx, new_value);
  50.                 p2 = update_point(right(p), (L + R) / 2 + 1, R          , idx, new_value);

  51.                 // return the pition where the overall minimum is
  52.                 return st[p] = (A[p1] <= A[p2]) ? p1 : p2;
  53.         }
  54. public:
  55.         SegmentTree(const std::vector<int> &_A)
  56.                 : A(_A), n(static_cast<int>(A.size()))  // copy content for local usage
  57.         {
  58.                 st.assign(4 * n, 0);            // create large enough vector of zeroes
  59.                 build(1, 0, n - 1);                                  // recursive build
  60.         }

  61.         int rmq(const int& i, const int& j)                          // overloading
  62.         {
  63.                 return rmq(1, 0, n - 1, i, j);
  64.         }

  65.         int update_point(const int& idx, const int& new_value)
  66.         {
  67.                 return update_point(1, 0, n - 1, idx, new_value);
  68.         }
  69. };

  70. #endif
复制代码
树状数组
  1. #ifndef FENWICK_TREE
  2. #define FENWICK_TREE
  3. #include <vector>

  4. class FenwickTree
  5. {
  6.         std::vector<int> ft;
  7.         int LSOne(int i) { return i & (-i); }
  8. public:
  9.         FenwickTree(int n)
  10.         {
  11.                 ft.assign(n+1, 0);
  12.         }
  13.         int rsq(int b)
  14.         {
  15.                 int sum = 0;
  16.                 for(; b; b -= LSOne(b))
  17.                         sum += ft[b];
  18.                 return sum;
  19.         }
  20.         int rsq(const int& a, const int& b)
  21.         {
  22.                 return rsq(b) - (a == 1 ? 0 : rsq(a-1));
  23.         }
  24.         // adjusts value of the k-th element by v (v can be +ve/inc or -ve/dec)
  25.         void adjust(int k, int v)                   // note: n = ft.size() - 1
  26.         {
  27.                 for (; k < static_cast<int>(ft.size()); k += LSOne(k))
  28.                         ft[k] += v;
  29.         }
  30. };

  31. #endif
复制代码
代码源自Steven & Felix, Competitive Programming.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-15 12:03:55 | 显示全部楼层
学习。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-18 19:20:09 | 显示全部楼层
这个必须要看看那啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-13 15:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表