Skip to content

Commit b01e3d1

Browse files
Add files via upload
1 parent 4d23738 commit b01e3d1

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
When a rook is placed on cell (x, y) it covers the whole row x and column y.
2+
3+
For every cell (x, y) in X1 < x < X and Y1 < y < Y2 to be covered, either
4+
1. All the rows should be covered.
5+
2. All the columns should be covered.
6+
7+
Suppose both these conditions are not true, then there is at least one cell (x, y)
8+
such that row x and column c are not covered.
9+
10+
-----
11+
12+
Maintain 2 Arrays of length N representing -
13+
14+
1. R[i] - Is row i covered
15+
2. C[j] - Is column j covered
16+
17+
We will update and find the sums of these ranges using segment trees.
18+
19+
Each query is answers in O(log n) time.
20+
21+
----
22+
23+
void update(int n, int left, int right, int index, int value, int tree_index)
24+
{
25+
if(index < left || right < index)
26+
{
27+
return;
28+
}
29+
30+
if(left == right)
31+
{
32+
sum_tree[n][tree_index] = value;
33+
//cout << (tree_index == 0 ? "Row" : "Column") << " Sum Tree [" << left << "," << right << "] = " << sum_tree[n][tree_index] << "\n";
34+
return;
35+
}
36+
37+
int mid = (left + right)/2;
38+
update(LEFT(n), left, mid, index, value, tree_index);
39+
update(RIGHT(n), mid + 1, right, index, value, tree_index);
40+
41+
sum_tree[n][tree_index] = sum_tree[LEFT(n)][tree_index] + sum_tree[RIGHT(n)][tree_index];
42+
//cout << (tree_index == 0 ? "Row" : "Column") << " Sum Tree [" << left << "," << right << "] = " << sum_tree[n][tree_index] << "\n";
43+
}
44+
45+
int get_sum(int n, int left, int right, int query_left, int query_right, int tree_index)
46+
{
47+
if(query_right < left || right < query_left)
48+
{
49+
return 0;
50+
}
51+
52+
if(query_left <= left && right <= query_right)
53+
{
54+
return sum_tree[n][tree_index];
55+
}
56+
57+
int mid = (left + right)/2;
58+
int left_sum = get_sum(LEFT(n), left, mid, query_left, query_right, tree_index);
59+
int right_sum = get_sum(RIGHT(n), mid + 1, right, query_left, query_right, tree_index);
60+
61+
return (left_sum + right_sum);
62+
}
63+
64+
int main()
65+
{
66+
ios_base::sync_with_stdio(false);
67+
cin.tie(NULL);
68+
69+
int n, no_of_queries;
70+
cin >> n >> no_of_queries;
71+
72+
memset(sum_tree, 0, sizeof(sum_tree));
73+
74+
const int ROW = 0, COLUMN = 1;
75+
vector <int> row_attackers(n + 1, 0), column_attackers(n + 1, 0);
76+
for(int i = 1; i <= no_of_queries; i++)
77+
{
78+
const int ADD = 1, REMOVE = 2, RECTANGLE = 3;
79+
int query;
80+
cin >> query;
81+
82+
switch(query)
83+
{
84+
case ADD: {
85+
int x, y;
86+
cin >> x >> y;
87+
88+
row_attackers[x]++;
89+
if(row_attackers[x] == 1)
90+
{
91+
update(1, 1, n, x, 1, ROW);
92+
}
93+
94+
column_attackers[y]++;
95+
if(column_attackers[y] == 1)
96+
{
97+
update(1, 1, n, y, 1, COLUMN);
98+
}
99+
}
100+
break;
101+
102+
case REMOVE : {
103+
int x, y;
104+
cin >> x >> y;
105+
106+
row_attackers[x]--;
107+
if(row_attackers[x] == 0)
108+
{
109+
update(1, 1, n, x, 0, ROW);
110+
}
111+
112+
column_attackers[y]--;
113+
if(column_attackers[y] == 0)
114+
{
115+
update(1, 1, n, y, 0, COLUMN);
116+
}
117+
}
118+
break;
119+
120+
case RECTANGLE :{
121+
int x1, y1, x2, y2;
122+
cin >> x1 >> y1 >> x2 >> y2;
123+
124+
if(x1 > x2)
125+
{
126+
swap(x1, x2);
127+
}
128+
129+
if(y1 > y2)
130+
{
131+
swap(y1, y2);
132+
}
133+
134+
int attacked_rows = get_sum(1, 1, n, x1, x2, ROW);
135+
int attacked_columns = get_sum(1, 1, n, y1, y2, COLUMN);
136+
//cout << "Rows attacked = " << attacked_rows << " Columns attacked = " << attacked_columns << "\n";
137+
138+
int every_cell_attacked = ( (attacked_rows == x2 - x1 + 1) || (attacked_columns == y2 - y1 + 1) );
139+
cout << (every_cell_attacked ? "Yes" : "No") << "\n";
140+
}
141+
}
142+
}
143+
144+
return 0;
145+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
The trick to this problem is to keep track of time.
2+
3+
Keep an array T,
4+
recording the time that an element was touched.
5+
6+
Also keep track of the last bulk update.
7+
8+
When doing a point update, check whether -
9+
1. T[i] > last_bulk_update_time
10+
11+
If yes, then the value at A[i], is A[i]
12+
13+
2. Else, the value at A[i] is the last bulk_update_value
14+
15+
-----
16+
17+
int main()
18+
{
19+
int no_of_elements, no_of_queries;
20+
cin >> no_of_elements >> no_of_queries;
21+
22+
vector <int> A(no_of_elements + 1);
23+
for(int i = 1; i <= no_of_elements; i++)
24+
{
25+
cin >> A[i];
26+
}
27+
28+
long long sum = 0;
29+
for(int i = 1; i <= no_of_elements; i++)
30+
{
31+
sum += A[i];
32+
}
33+
34+
int last_replace_all_time = -1, last_replace_all_value = 0;
35+
vector <int> last_touched(no_of_elements + 1, 0);
36+
for(int i = 1; i <= no_of_queries; i++)
37+
{
38+
const int REPLACE_ONE = 1, REPLACE_ALL = 2;
39+
int query, index, value;
40+
cin >> query;
41+
42+
switch(query)
43+
{
44+
case REPLACE_ONE: cin >> index >> value;
45+
if(last_touched[index] > last_replace_all_time)
46+
{
47+
sum += (value - A[index]);
48+
}
49+
else
50+
{
51+
sum += (value - last_replace_all_value);
52+
}
53+
54+
A[index] = value;
55+
last_touched[index] = i;
56+
break;
57+
58+
case REPLACE_ALL: cin >> value;
59+
60+
sum = no_of_elements*1LL*value;
61+
62+
last_replace_all_value = value;
63+
last_replace_all_time = i;
64+
}
65+
66+
cout << sum << "\n";
67+
}
68+
69+
return 0;
70+
}

0 commit comments

Comments
 (0)