Skip to content

Commit 4046d5e

Browse files
Add files via upload
1 parent 83a8f2f commit 4046d5e

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include <cstdio>
2+
#include <cstring>
3+
4+
#define LEFT(n) ( (n << 1) )
5+
#define RIGHT(n) ( (n << 1)|1 )
6+
#define max(a, b) (a > b ? a : b)
7+
8+
const int MAX_N = 3e5 + 5;
9+
long long sum_tree[3*MAX_N];
10+
long long max_tree[3*MAX_N];
11+
long long A[MAX_N];
12+
13+
void swap(int &a, int &b)
14+
{
15+
int temp = a;
16+
a = b;
17+
b = temp;
18+
}
19+
20+
long long square(long long n)
21+
{
22+
return n*n;
23+
}
24+
25+
long long square_root(long long n)
26+
{
27+
long long left = 1, right = 1e9;
28+
29+
while(left <= right)
30+
{
31+
long long mid = (left + right) >> 1;
32+
33+
if(square(mid) <= n)
34+
{
35+
if(square(mid + 1) > n)
36+
{
37+
return mid;
38+
}
39+
else
40+
{
41+
left = mid + 1;
42+
}
43+
}
44+
else
45+
{
46+
right = mid;
47+
}
48+
}
49+
}
50+
51+
void build(int n, int left, int right)
52+
{
53+
if(left == right)
54+
{
55+
sum_tree[n] = max_tree[n] = A[left];
56+
return;
57+
}
58+
59+
int mid = (left + right) >> 1;
60+
build(LEFT(n), left, mid);
61+
build(RIGHT(n), mid + 1, right);
62+
63+
max_tree[n] = max(max_tree[LEFT(n)], max_tree[RIGHT(n)]);
64+
sum_tree[n] = sum_tree[LEFT(n)] + sum_tree[RIGHT(n)];
65+
}
66+
67+
void update(int n, int left, int right, int query_left, int query_right)
68+
{
69+
if(query_right < left || right < query_left || max_tree[n] == 1)
70+
return;
71+
72+
if(left == right)
73+
{
74+
A[left] = square_root(A[left]);
75+
sum_tree[n] = max_tree[n] = A[left]; //printf("A[%d] is now %lld\n", left, A[left]);
76+
return;
77+
}
78+
79+
int mid = (left + right) >> 1;
80+
update(LEFT(n), left, mid, query_left, query_right);
81+
update(RIGHT(n), mid + 1, right, query_left, query_right);
82+
83+
sum_tree[n] = sum_tree[LEFT(n)] + sum_tree[RIGHT(n)];
84+
max_tree[n] = max(max_tree[LEFT(n)], max_tree[RIGHT(n)]); //printf("S[%d] = %lld\n", n, sum_tree[n]);
85+
}
86+
87+
long long sum(int n, int left, int right, int query_left, int query_right)
88+
{
89+
if(query_right < left || right < query_left)
90+
return 0;
91+
92+
if(query_left <= left && right <= query_right)
93+
return sum_tree[n];
94+
95+
int mid = (left + right) >> 1;
96+
long long left_sum = sum(LEFT(n), left, mid, query_left, query_right);
97+
long long right_sum = sum(RIGHT(n), mid + 1, right, query_left, query_right);
98+
99+
return (left_sum + right_sum);
100+
}
101+
102+
void solve(int no_of_elements)
103+
{
104+
for(int i = 1; i <= no_of_elements; i++)
105+
scanf("%lld", &A[i]);
106+
107+
memset(max_tree, 0, sizeof(max_tree));
108+
memset(sum_tree, 0, sizeof(sum_tree));
109+
build(1, 1, no_of_elements);
110+
111+
int no_of_queries;
112+
scanf("%d", &no_of_queries);
113+
114+
while(no_of_queries--)
115+
{
116+
const int SUM = 1, UPDATE = 0;
117+
int query_type, left, right;
118+
scanf("%d %d %d", &query_type, &left, &right);
119+
120+
if(left > right) swap(left, right);
121+
122+
if(query_type == SUM)
123+
{
124+
long long answer_sum = sum(1, 1, no_of_elements, left, right);
125+
printf("%lld\n", answer_sum);
126+
}
127+
if(query_type == UPDATE)
128+
{
129+
update(1, 1, no_of_elements, left, right);
130+
}
131+
}
132+
printf("\n");
133+
}
134+
135+
int main()
136+
{
137+
for(int i = 1; ; i++)
138+
{
139+
int no_of_elements;
140+
141+
if(scanf("%d", &no_of_elements) < 1)
142+
break;
143+
144+
printf("Case #%d:\n", i);
145+
solve(no_of_elements);
146+
}
147+
148+
return 0;
149+
}

0 commit comments

Comments
 (0)