Skip to content

Commit cbca0f2

Browse files
Add files via upload
1 parent 5db7b97 commit cbca0f2

File tree

4 files changed

+259
-0
lines changed

4 files changed

+259
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from collections import Counter
2+
for _ in range(int(input())):
3+
n = int(input())
4+
arr = list(map(int, input().split()))
5+
c = Counter(arr)
6+
maxi = max(c.values())
7+
print(n - maxi)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
for _ in range(int(input())):
2+
n = int(input())
3+
arr = list(map(int, input().split()))
4+
arr = [x - 1 for x in arr]
5+
6+
i = 0
7+
while i < n:
8+
if arr[i] == i:
9+
i += 1
10+
continue
11+
12+
elif arr[i] == i + 1 and arr[i + 1] == i:
13+
i += 2
14+
continue
15+
16+
else:
17+
print("NO")
18+
break
19+
else:
20+
print("YES")
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
for _ in range(int(input())):
2+
3+
n = int(input())
4+
if n % 2 == 0:
5+
for i in range(1, n + 1):
6+
print((i + 1) // 2, end=" ")
7+
print()
8+
continue
9+
10+
if n < 27:
11+
print(-1)
12+
continue
13+
14+
ans = [0] * n
15+
ans[0] = 1
16+
ans[9] = 1
17+
ans[25] = 1
18+
ans[26] = 2
19+
ans[22] = 2
20+
21+
cur = 3
22+
i = 0
23+
while i < n:
24+
if ans[i] == 0:
25+
ans[i] = cur
26+
ans[i + 1] = cur
27+
cur += 1
28+
i += 2
29+
else:
30+
i += 1
31+
32+
print(" ".join(map(str, ans)))
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/**CF2031D
2+
* Observe that the connected components are in contiguous ranges (simple case analysis: suppose we can go from i -> j for i < j, then we can go to anything between i and j).
3+
* Consider going through the array from the left to right. We figure out how big the leftmost connected component is. To do so, we repeatedly expand it to the right as long as
4+
* the maximum of the connected component is bigger than some element on the right. For the sake of simplicity, we pick the minimum element on the right to expand to. When we can
5+
* no longer expand, that is the largest connected component. We can then recurse to the subproblem of dealing with the next connected component starting immdiately after the
6+
* current connected component. Observe that we can do up to O(n) expansions in total since each expansion increses the size of some connected component by at least 1 and the
7+
* sum of connected component sizes is n. We can use either a sparse table or segment tree for finding the index of the minimum element of a range, I just chose a segment tree
8+
* because I had the code for it but a sparse table is more efficient.
9+
*
10+
* Time complexity: O(n log n) for each test case
11+
* Space complexity: O(n)
12+
*/
13+
#pragma GCC optimize("Ofast")
14+
#pragma GCC optimize("unroll-loops")
15+
#include <bits/stdc++.h>
16+
using namespace std;
17+
18+
typedef long long ll;
19+
typedef vector<int> vi;
20+
#define fast_cin() \
21+
ios_base::sync_with_stdio(false); \
22+
cin.tie(NULL); \
23+
cout.tie(NULL);
24+
25+
typedef long long ll;
26+
struct Node {
27+
int s, e;
28+
ll mn, mx, sum, add_val, set_val;
29+
ll mn_idx, mx_idx; // left most index of minimum and maximum
30+
ll num_mn, num_mx; // number of minimums and maximums
31+
bool lset;
32+
Node *l, *r;
33+
Node(int _s, int _e, int A[] = NULL) : s(_s), e(_e), mn(0), mx(0), sum(0), mn_idx(_s), mx_idx(_s), num_mn(_e - _s + 1), num_mx(_e - _s + 1), lset(0), add_val(0), set_val(0), l(NULL), r(NULL) {
34+
if (A == NULL) return;
35+
if (s == e) {
36+
mn = mx = sum = A[s];
37+
} else {
38+
l = new Node(s, (s + e) >> 1, A), r = new Node((s + e + 2) >> 1, e, A);
39+
combine();
40+
}
41+
}
42+
void create_children() {
43+
if (s == e) return;
44+
if (l != NULL) return;
45+
int m = (s + e) >> 1;
46+
l = new Node(s, m);
47+
r = new Node(m + 1, e);
48+
}
49+
void self_set(ll v) {
50+
lset = 1;
51+
mn = mx = set_val = v;
52+
mn_idx = mx_idx = s; // left most index
53+
num_mn = num_mx = e - s + 1; // all are the same
54+
sum = v * (e - s + 1);
55+
add_val = 0;
56+
}
57+
void self_add(ll v) {
58+
if (lset) {
59+
self_set(v + set_val);
60+
return;
61+
}
62+
mn += v, mx += v, add_val += v;
63+
sum += v * (e - s + 1);
64+
}
65+
void lazy_propagate() {
66+
if (s == e) return;
67+
if (lset) {
68+
l->self_set(set_val), r->self_set(set_val);
69+
lset = set_val = 0;
70+
}
71+
if (add_val != 0) {
72+
l->self_add(add_val), r->self_add(add_val);
73+
add_val = 0;
74+
}
75+
}
76+
void combine() {
77+
if (l == NULL) return;
78+
sum = l->sum + r->sum;
79+
mn = min(l->mn, r->mn);
80+
mx = max(l->mx, r->mx);
81+
mn_idx = l->mn <= r->mn ? l->mn_idx : r->mn_idx;
82+
mx_idx = l->mx >= r->mx ? l->mx_idx : r->mx_idx;
83+
num_mn = (l->mn == mn ? l->num_mn : 0) + (r->mn == mn ? r->num_mn : 0);
84+
num_mx = (l->mx == mx ? l->num_mx : 0) + (r->mx == mx ? r->num_mx : 0);
85+
}
86+
87+
#define UPDATE(name) \
88+
void name(int x, int y, ll v) { \
89+
if (s == x && e == y) { \
90+
self_##name(v); \
91+
return; \
92+
} \
93+
int m = (s + e) >> 1; \
94+
create_children(); \
95+
lazy_propagate(); \
96+
if (x <= m) l->name(x, min(y, m), v); \
97+
if (y > m) r->name(max(x, m + 1), y, v); \
98+
combine(); \
99+
}
100+
UPDATE(add) // generates add
101+
UPDATE(set) // generates set
102+
103+
#define QUERY(name, fn, var, lazyfn) \
104+
ll range_##name(int x, int y) { \
105+
if (s == x && e == y) return var; \
106+
/* optimise for when all the elements in the range are equal*/ \
107+
if (l == NULL || lset) return lazyfn(var); \
108+
int m = (s + e) >> 1; \
109+
lazy_propagate(); \
110+
if (y <= m) return l->range_##name(x, y); \
111+
if (x > m) return r->range_##name(x, y); \
112+
return fn(l->range_##name(x, m), r->range_##name(m + 1, y)); \
113+
}
114+
115+
#define SAME(var) (var)
116+
#define PART(var) ((var) / (e - s + 1) * (y - x + 1))
117+
#define SUM(a, b) ((a) + (b))
118+
QUERY(min, min, mn, SAME) // generates range_min
119+
QUERY(max, max, mx, SAME) // generates range_max
120+
QUERY(sum, SUM, sum, PART) // generates range_sum
121+
QUERY(num_min, SUM, num_mn, PART) // generates range_num_min
122+
QUERY(num_max, SUM, num_mx, PART) // generates range_num_max
123+
124+
pair<ll, ll> get_min_with_idx(pair<ll, ll> a, pair<ll, ll> b) {
125+
if (a.first < b.first) return a;
126+
if (a.first > b.first) return b;
127+
return a.second < b.second ? a : b; // right most index
128+
}
129+
pair<ll, ll> range_min_with_idx(int x, int y) { // returns (mn, idx)
130+
if (s == x && e == y) return {mn, mn_idx};
131+
if (l == NULL || lset) return {mn, mn_idx};
132+
int m = (s + e) >> 1;
133+
lazy_propagate();
134+
if (y <= m) return l->range_min_with_idx(x, y);
135+
if (x > m) return r->range_min_with_idx(x, y);
136+
return get_min_with_idx(l->range_min_with_idx(x, m), r->range_min_with_idx(m + 1, y));
137+
}
138+
139+
pair<ll, ll> get_max_with_idx(pair<ll, ll> a, pair<ll, ll> b) {
140+
if (a.first > b.first) return a;
141+
if (a.first < b.first) return b;
142+
return a.second > b.second ? a : b; // right most index
143+
}
144+
pair<ll, ll> range_max_with_idx(int x, int y) { // returns (mx, idx)
145+
if (s == x && e == y) return {mx, mx_idx};
146+
if (l == NULL || lset) return {mx, mx_idx};
147+
int m = (s + e) >> 1;
148+
lazy_propagate();
149+
if (y <= m) return l->range_max_with_idx(x, y);
150+
if (x > m) return r->range_max_with_idx(x, y);
151+
return get_max_with_idx(l->range_max_with_idx(x, m), r->range_max_with_idx(m + 1, y));
152+
}
153+
154+
~Node() {
155+
if (l != NULL) delete l;
156+
if (r != NULL) delete r;
157+
}
158+
};
159+
160+
int main() {
161+
fast_cin();
162+
int tc;
163+
cin >> tc;
164+
while (tc--) {
165+
int n;
166+
cin >> n;
167+
vector<int> a(n);
168+
for (int i = 0; i < n; i++) {
169+
cin >> a[i];
170+
}
171+
Node *seg = new Node(0, n - 1, a.data());
172+
173+
vector<int> ans(n, -1); // the component it is in
174+
for (int left = 0; left < n;) {
175+
int right = left;
176+
int maxi = a[left];
177+
while (right < n - 1) {
178+
auto [mn, mn_idx] = seg->range_min_with_idx(right + 1, n - 1);
179+
if (mn >= maxi) break;
180+
right = mn_idx;
181+
maxi = seg->range_max(left, right);
182+
}
183+
184+
for (int j = left; j <= right; j++) {
185+
ans[j] = maxi;
186+
}
187+
188+
left = right + 1;
189+
}
190+
191+
for (int i = 0; i < n; i++) {
192+
cout << ans[i] << " ";
193+
}
194+
cout << endl;
195+
196+
delete seg;
197+
}
198+
199+
return 0;
200+
}

0 commit comments

Comments
 (0)