Skip to content

Instantly share code, notes, and snippets.

@jiunbae
Created March 24, 2016 13:10
Show Gist options
  • Save jiunbae/962f44874b729d017cc9 to your computer and use it in GitHub Desktop.
Save jiunbae/962f44874b729d017cc9 to your computer and use it in GitHub Desktop.
/**
segment tree with lazy propagation
init with (vector<T>)
use update to update value with range
query return value of operation defined oper function
*/
#include <iostream>
#include <cmath>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
template <typename T>
class lazy_tree
{
public:
lazy_tree(const vector<T>& vec)
{
raw.assign(vec.begin(), vec.end());
tree.assign(2 * pow(2, (int)(ceil(log2(raw.size())))), 0);
lazy.assign(tree.begin(), tree.end());
init_util(1, 0, raw.size() - 1);
}
~lazy_tree() {}
void update(T qstart, T qend, T value)
{
update_util(1, qstart, qend, 0, raw.size() - 1, value);
}
T query(T qstart, T qend)
{
return query_util(1, qstart, qend, 0, raw.size() - 1);
}
private:
vector<T> tree, lazy, raw;
T INF = 0;
T oper(T first, T second)
{
return first + second;
}
void init_util(T index, T start, T end)
{
if (index > tree.size() - 1)
return;
if (start > end)
return;
if (start == end)
{
tree[index] = raw[start];
return;
}
init_util(index * 2, start, (start + end) / 2);
init_util(index * 2 + 1, (start + end) / 2 + 1, end);
tree[index] = oper(tree[index * 2], tree[index * 2 + 1]);
}
void update_util(T index, T qstart, T qend, T start, T end, T value)
{
if (lazy[index])
{
tree[index] += (end - start + 1) * lazy[index];
if (start - end)
{
lazy[index * 2] += lazy[index];
lazy[index * 2 + 1] += lazy[index];
}
lazy[index] = 0;
}
if (start > end || start > qend || end < qstart)
return;
if (start >= qstart && end <= qend)
{
tree[index] += (end - start + 1)*value;
if (start - end)
{
lazy[index * 2] += value;
lazy[index * 2 + 1] += value;
}
return;
}
update_util(index * 2, qstart, qend, start, (start + end) / 2, value);
update_util(index * 2 + 1, qstart, qend, (start + end) / 2 + 1, end, value);
tree[index] = oper(tree[index * 2], tree[index * 2 + 1]);
}
T query_util(T index, T qstart, T qend, T start, T end)
{
if (lazy[index])
{
tree[index] += (end - start + 1) * lazy[index];
if (start - end)
{
lazy[index * 2] += lazy[index];
lazy[index * 2 + 1] += lazy[index];
}
lazy[index] = 0;
}
if (start > end || start > qend || end < qstart)
return INF;
if (start >= qstart && end <= qend)
return tree[index];
return oper(query_util(index * 2, qstart, qend, start, (start + end) / 2),
query_util(index * 2 + 1, qstart, qend, (start + end) / 2 + 1, end));
}
};
/**
tested main
*/
/*
int main(int argc, char * argv[])
{
long long int n, m, k, t, a, b, c; cin >> n >> m >> k;
vector<long long int> v;
while (n--)
{
cin >> t;
v.push_back(t);
}
lazy_tree<long long int> tree(v);
while (!m && !k)
{
cin >> t;
switch (t)
{
case 1:
cin >> a >> b >> c;
tree.update(a-1, b-1, c);
m--;
break;
case 2:
cin >> a >> b;
cout << tree.query(a - 1, b - 1) << endl;
k--;
break;
}
}
return 0;
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment