P10280 [USACO24OPEN] Cowreography G 题解

Description

奶牛们组了一支舞蹈队,Farmer John 是她们的编舞!舞蹈队最新而最精彩的舞蹈有 NN 头奶牛(2N1062\le N\le 10^6)排成一行。舞蹈中的每次动作都涉及两头奶牛,至多相距 KK 个位置(1K<N1\le K < N),优雅地跳起并降落在对方的位置上。

队伍中有两种奶牛——更赛牛(Guernsey)和荷斯坦牛(Holstein)。因此,Farmer John 将这一舞蹈记录为一系列长为 NN01 字符串,其中 0 代表更赛牛,1 代表荷斯坦牛,整个字符串表示奶牛在这一行中是如何排列的。

不幸的是,Farmer Nhoj(对手团队的编舞)蓄意破坏了这一舞蹈,并清除了除第一个和最后一个 01 字符串之外的所有内容!由于一场大型比赛即将开始,Farmer John 必须抓紧每一秒重建这一舞蹈。

给定这两个 01 字符串,帮助 Farmer John 求出舞蹈中的最小动作数量!

Solution

考虑交换一对 i,j(aiaj)i,j(a_i\neq a_j) 所用的代价,结论是 ijk\left\lceil\frac{|i-j|}{k}\right\rceil

证明就考虑数学归纳法,不妨设 i<ji<j 且长度小于 jij-i 的已经满足结论,容易发现对于 jikj-i\leq k(i,j)(i,j) 一定满足条件。

对于 i<s<ji<s<j,如果 ai=asa_i=a_s 则先交换 (j,s)(j,s) 再交换 (i,s)(i,s),否则先交换 (i,s)(i,s) 在交换 (j,s)(j,s),对应的代价为 sik+jsk\left\lceil\frac{s-i}{k}\right\rceil+\left\lceil\frac{j-s}{k}\right\rceil,容易发现当 ssi+ki+k 时可以取到最小值,即为 ijk\left\lceil\frac{|i-j|}{k}\right\rceil

有了这个结论就可发现这里的交换一定是两两匹配,即在一张二分图上匹配。

如果没有取上整就从前往后扫,如果 aibia_i\neq b_i 就找到任意一个还没匹配的 jj 使得 aiaja_i\neq a_j 匹配,容易发现这个一定是最小值。

如果有了取上整,感性理解可以发现这里需要让 (ij)modk(i-j)\bmod k 的和尽可能小,所以只要把上面选任意一个匹配变为选使得 (ij)modk(i-j)\bmod k 最小的 jj 匹配即可。

时间复杂度:O(nlogn)O(n\log n)

Code

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
#include <bits/stdc++.h>

// #define int int64_t

int n, k;
std::string a, b;

void dickdreamer() {
std::cin >> n >> k >> a >> b;
a = " " + a, b = " " + b;
std::set<std::pair<int, int>> st[2];
int64_t ans = 0;
for (int i = 1; i <= n; ++i) {
if (a[i] == b[i]) continue;
int oa = a[i] - '0', ob = b[i] - '0';
if (!st[ob].empty()) {
auto it = st[ob].lower_bound({i % k, 0});
if (it == st[ob].end()) it = st[ob].begin();
ans += (i - it->second + k - 1) / k;
st[ob].erase(it);
} else {
st[oa].emplace(i % k, i);
}
}
std::cout << ans << '\n';
}

int32_t main() {
#ifdef ORZXKR
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) dickdreamer();
// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
return 0;
}

P10280 [USACO24OPEN] Cowreography G 题解
https://sobaliuziao.github.io/2024/07/23/post/2be0472f.html
作者
Egg_laying_master
发布于
2024年7月23日
许可协议