// Sergey Kopeliovich (aka Burunduk1)
// 07.02.2013
// modification on the segment: version with templates
#include <cstdio>
#include <ctime>
#include <algorithm>
using namespace std;
const int maxn = 1 << 8;
int t[maxn * 2];
int add[maxn * 2];
// v = vertex, [vl..vr] = segment of the vertex, [L..R] = query
template <int v, int vl, int vr>
struct Tree
{
static int Get( int L, int R )
{
if (vr < L || vl > R)
return 0;
if (L <= vl && vr <= R)
return t[v];
const int vm = (vl + vr) / 2;
int sum = (min(R, vr) - max(L, vl) + 1) * add[v];
sum += Tree<2 * v, vl, vm>::Get(L, R);
sum += Tree<2 * v + 1, vm + 1, vr>::Get(L, R);
return sum;
}
static void Add( int L, int R, int x )
{
if (vr < L || vl > R)
return;
if (L <= vl && vr <= R)
{
add[v] += x;
t[v] += x * (vr - vl + 1);
return;
}
const int vm = (vl + vr) / 2;
Tree<2 * v, vl, vm>::Add(L, R, x);
Tree<2 * v + 1, vm + 1, vr>::Add(L, R, x);
t[v] = t[2 * v] + t[2 * v + 1] + add[v] * (vr - vl + 1);
}
};
template <int v, int vl>
struct Tree<v, vl, vl>
{
static int Get( int L, int R )
{
return (L <= vl && vl <= R) ? t[v] : 0;
}
static void Add( int L, int R, int x )
{
if (L <= vl && vl <= R)
add[v] += x, t[v] += x;
}
};
typedef Tree<1, 0, maxn - 1> T;
// Testing
int main()
{
int L = 5, R = 10;
T::Add(L, R, 30);
printf("%d\n", T::Get(L, R));
int N = (int)1e7;
L = 1, R = 1;
while (N--)
{
L = L * 3, R = R * 7;
L &= maxn - 1, R &= maxn - 1;
T::Add(min(L, R), max(L, R), 1);
}
printf("%d\n", T::Get(min(L, R), max(L, R)));
printf("time = %.2f\n", 1. * clock() / CLOCKS_PER_SEC);
return 0;
}