TheAlgorithms-C-Plus-Plus/range_queries/segTree.cpp

92 lines
2.1 KiB
C++
Raw Normal View History

2017-08-29 17:34:30 +08:00
#include <bits/stdc++.h>
#define MAX 4000000
using namespace std;
typedef long long ll;
2019-08-21 10:10:08 +08:00
void ConsTree(ll arr[], ll segtree[], ll low, ll high, ll pos)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
if (low == high)
2017-08-29 17:34:30 +08:00
{
segtree[pos] = arr[low];
return;
}
2019-08-21 10:10:08 +08:00
ll mid = (low + high) / 2;
ConsTree(arr, segtree, low, mid, 2 * pos + 1);
ConsTree(arr, segtree, mid + 1, high, 2 * pos + 2);
segtree[pos] = segtree[2 * pos + 1] + segtree[2 * pos + 2];
2017-08-29 17:34:30 +08:00
}
2019-08-21 10:10:08 +08:00
ll query(ll segtree[], ll lazy[], ll qlow, ll qhigh, ll low, ll high, ll pos)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
if (low > high)
2017-08-29 17:34:30 +08:00
return 0;
2019-08-21 10:10:08 +08:00
if (qlow > high || qhigh < low)
2017-08-29 17:34:30 +08:00
return 0;
2019-08-21 10:10:08 +08:00
if (lazy[pos] != 0)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
segtree[pos] += lazy[pos] * (high - low + 1);
if (low != high)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
lazy[2 * pos + 1] += lazy[pos];
lazy[2 * pos + 2] += lazy[pos];
2017-08-29 17:34:30 +08:00
}
lazy[pos] = 0;
}
2019-08-21 10:10:08 +08:00
if (qlow <= low && qhigh >= high)
2017-08-29 17:34:30 +08:00
return segtree[pos];
2019-08-21 10:10:08 +08:00
ll mid = (low + high) / 2;
return query(segtree, lazy, qlow, qhigh, low, mid, 2 * pos + 1) + query(segtree, lazy, qlow, qhigh, mid + 1, high, 2 * pos + 2);
2017-08-29 17:34:30 +08:00
}
2019-08-21 10:10:08 +08:00
void update(ll segtree[], ll lazy[], ll start, ll end, ll delta, ll low, ll high, ll pos)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
if (low > high)
2017-08-29 17:34:30 +08:00
return;
2019-08-21 10:10:08 +08:00
if (lazy[pos] != 0)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
segtree[pos] += lazy[pos] * (high - low + 1);
if (low != high)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
lazy[2 * pos + 1] += lazy[pos];
lazy[2 * pos + 2] += lazy[pos];
2017-08-29 17:34:30 +08:00
}
lazy[pos] = 0;
}
2019-08-21 10:10:08 +08:00
if (start > high || end < low)
2017-08-29 17:34:30 +08:00
return;
2019-08-21 10:10:08 +08:00
if (start <= low && end >= high)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
segtree[pos] += delta * (high - low + 1);
if (low != high)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
lazy[2 * pos + 1] += delta;
lazy[2 * pos + 2] += delta;
2017-08-29 17:34:30 +08:00
}
return;
}
2019-08-21 10:10:08 +08:00
ll mid = (low + high) / 2;
update(segtree, lazy, start, end, delta, low, mid, 2 * pos + 1);
update(segtree, lazy, start, end, delta, mid + 1, high, 2 * pos + 2);
segtree[pos] = segtree[2 * pos + 1] + segtree[2 * pos + 2];
2017-08-29 17:34:30 +08:00
}
2019-08-21 10:10:08 +08:00
int main()
{
ll n, c;
scanf("%lld %lld", &n, &c);
ll arr[n] = {0}, p, q, v, choice;
ll segtree[MAX], lazy[MAX] = {0};
ConsTree(arr, segtree, 0, n - 1, 0);
while (c--)
{
scanf("%lld", &choice);
if (choice == 0)
2017-08-29 17:34:30 +08:00
{
2019-08-21 10:10:08 +08:00
scanf("%lld %lld %lld", &p, &q, &v);
update(segtree, lazy, p - 1, q - 1, v, 0, n - 1, 0);
2017-08-29 17:34:30 +08:00
}
2019-08-21 10:10:08 +08:00
else
{
scanf("%lld %lld", &p, &q);
printf("%lld\n", query(segtree, lazy, p - 1, q - 1, 0, n - 1, 0));
}
}
2017-08-29 17:34:30 +08:00
return 0;
}