-
Notifications
You must be signed in to change notification settings - Fork 307
/
Copy pathsquare_root_decomposition
89 lines (79 loc) · 2 KB
/
square_root_decomposition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// C++ program to demonstrate working of Square Root
// Decomposition.
//This is a programme that will help to reduce time complexity
//for big arrays
#include "iostream"
#include "math.h"
using namespace std;
#define MAXN 10000
#define SQRSIZE 100
int arr[MAXN]; // original array
int block[SQRSIZE]; // decomposed array
int blk_sz; // block size
// Time Complexity : O(1)
void update(int idx, int val)
{
int blockNumber = idx / blk_sz;
block[blockNumber] += val - arr[idx];
arr[idx] = val;
}
// Time Complexity : O(sqrt(n))
int query(int l, int r)
{
int sum = 0;
while (l<r and l%blk_sz!=0 and l!=0)
{
// traversing first block in range
sum += arr[l];
l++;
}
while (l+blk_sz <= r)
{
// traversing completely overlapped blocks in range
sum += block[l/blk_sz];
l += blk_sz;
}
while (l<=r)
{
// traversing last block in range
sum += arr[l];
l++;
}
return sum;
}
// Fills values in input[]
void preprocess(int input[], int n)
{
// initiating block pointer
int blk_idx = -1;
// calculating size of block
blk_sz = sqrt(n);
// building the decomposed array
for (int i=0; i<n; i++)
{
arr[i] = input[i];
if (i%blk_sz == 0)
{
// entering next block
// incementing block pointer
blk_idx++;
}
block[blk_idx] += arr[i];
}
}
// Driver code
int main()
{
// We have used separate array for input because
// the purpose of this code is to explain SQRT
// decomposition in competitive programming where
// we have multiple inputs.
int input[] = {1, 5, 2, 4, 6, 1, 3, 5, 7, 10};
int n = sizeof(input)/sizeof(input[0]);
preprocess(input, n);
cout << "query(3,8) : " << query(3, 8) << endl;
cout << "query(1,6) : " << query(1, 6) << endl;
update(8, 0);
cout << "query(8,8) : " << query(8, 8) << endl;
return 0;
}