比赛链接

D题

1的移动转换为0的移动,所有的0都要移动到1的两侧,统计每个0左右两侧1的个数,取最小值,则为移动该0所需的最小步数。

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
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);

int n;
string s;
cin >> n >> s;
std::vector<int> dp1(n), dp2(n);

for (int i = 1; i < n; i++) {
if (s[i - 1] == '1') {
dp1[i] = dp1[i - 1] + 1;
} else {
dp1[i] = dp1[i - 1];
}
}
for (int i = n - 2; i >= 0; i--) {
if (s[i + 1] == '1') {
dp2[i] = dp2[i + 1] + 1;
} else {
dp2[i] = dp2[i + 1];
}
}
i64 ans = 0;
for (int i = 0; i < n; i++) {
if (s[i] == '0') {
ans += std::min(dp1[i], dp2[i]);
}
}
cout << ans;
return 0;
}

E题

枚举**$[1,N]$中的每一个数字i,查找i可以是A数组中多少个数字的因子,取个数$\geq k$的因子,从小到大枚举这些因子可以作为数字$[1,N]$**中哪些数字的因子,并填充答案,由于所有因子是从小到大枚举,因此较大的因子会覆盖原先较小的因子。

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
int main() {
int n, k;
const int N = 1000005;
n = read<int>();
k = read<int>();
std::vector<int> a(n);
std::vector<int> cnt(N);
std::vector<int> fcnt(N);
for (int i = 0; i < n; i++) {
a[i] = read<int>();
cnt[a[i]]++;
fcnt[a[i]]++;
}
for (int i = 1; i < N; i++) {
for (int j = 2; i * j < N; j++) {
fcnt[i] += cnt[i * j];
}
}
std::vector<int> fac;
std::vector<int> ans(N);
for (int i = 1; i < N; i++) {
if (fcnt[i] >= k) {
fac.push_back(i);
}
}
for (int i : fac) {
for (int j = 1; j * i < N; j++) {
ans[j * i] = i;
}
}
for (int i : a) {
print(ans[i], '\n');
}

return 0;
}

F题

从1到n枚举A[i],并修改dp表,dp[j]表示长度为j的LIS的最小结尾。将询问按Ri的下标索引存储起来,以便于离线查询。二分寻找对应位置:

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
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int n, q;
cin >> n >> q;
std::vector<int> a(n);
for (int & i : a) {
cin >> i;
}

std::vector<std::vector<PII>> que(n);
for (int i = 0; i < q; i++) {
int r, x;
cin >> r >> x;
que[r - 1].push_back({i, x});
}

std::vector<int> dp(n, INF);
std::vector<int> ans(q);
for (int i = 0; i < n; i++) {
*(std::lower_bound(dp.begin(), dp.end(), a[i])) = a[i];
for (auto & [id, x] : que[i]) {
ans[id] = std::upper_bound(dp.begin(), dp.end(), x) - dp.begin();
}
}
for (int i : ans) {
cout << i << "\n";
}
return 0;
}