首页 > 其他分享 >P10280 [USACO24OPEN] Cowreography G 题解

P10280 [USACO24OPEN] Cowreography G 题解

时间:2024-07-23 21:30:17浏览次数:10  
标签:std 奶牛 匹配 题解 舞蹈 USACO24OPEN Farmer John Cowreography

Description

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

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

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

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

Solution

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

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

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

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

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

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

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

Code

#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;
}

标签:std,奶牛,匹配,题解,舞蹈,USACO24OPEN,Farmer,John,Cowreography
From: https://www.cnblogs.com/Scarab/p/18319669

相关文章

  • 基因改造 题解
    前言题目链接:Hydro&bzoj。题意简述求匹配串\(S\)中和模式串\(T\)匹配的子串。两个串被定义为匹配的,当且仅当一个串任意交换字符后和另一个串相等。例如\(\texttt{12321}\)和\(\texttt{21312}\)匹配,因为前者交换\(\texttt{1}\)和\(\texttt{2}\)后与后者等价。当然......
  • CF521E Cycling City 题解
    Description给定一张\(n\)个点\(m\)条边的无向简单图。问图中能否找到两个点,满足这两个点之间有至少三条完全不相交的简单路径。\(n,m\le2\times10^5\),图不保证连通。Solution容易发现有解地充要条件是存在两个环有边交,考虑在dfs树上做这件事。注意到非树边一定......
  • CF1990F Polygonal Segments 题解
    题目链接:https://codeforces.com/contest/1990/problem/F赛时想到了一个略显抽象的做法,但因为写反了一个判断导致没能过掉。赛后调参卡过,用时\(3.5/8\)秒。为了不丢失这个idea最终还是决定写个题解记录一下。题意简述给定一个数组\(a_{1..n}\),执行以下查询:查询区间\([......
  • 题解:P10800 「CZOI-R1」卡牌
    \(\text{Link}\)最近做的最神金的一道数据结构题。题意给出\(m\)个值域为\([1,n]\)的四元组\(t_{i,0\sim3}\),定义四元组\(A\)胜于四元组\(B\)当且仅当最多存在一个\(j\in[0,3]\)使得\(A_j\leB_j\),求出有多少个值域为\([1,n]\)的四元组\(A\)胜于所有的\(t_{1......
  • 题解:P10717「KDOI-05」简单的树上问题
    \(\text{Link}\)题意给你一颗\(n\)个结点的树,有\(k\)次操作,第\(i\)次操作:每个点初始都处于未激活状态;以\(p_{i,j}\)的概率激活点\(j\);对于每个未激活的点\(i\),如果存在激活的结点\(j,k\)且\(i\)在\(j\)到\(k\)的路径上,则\(i\)也会被激活。给出\(v_{i......
  • NOI2024 题解
    D2T3树形图首先判掉一些case将任意一个\(1\)类点定为根,求出一棵dfs树,则图上的非树边只有返祖边,没有横叉边。\(1\)类点考虑在这棵dfs树的基础上求出所有\(1\)类点:考虑\(fa_u\tou\)这条边被几条返祖边覆盖了,由于这是一个强连通分量,所以子树中至少有一条返祖边覆......
  • 题解:CF1992F Valuable Cards
    Part1:前言题目翻译在他最喜欢的咖啡馆里,Kmes再次想尝尝皮草大衣下的鲱鱼。以前,这对他来说并不难,但咖啡馆最近推出了一项新的购买政策。现在,为了进行购买,Kmes需要解决以下问题:在他面前摆放着\(n\)张不同价格的卡,第\(i\)张卡的价格为\(a_i\),在这些价格中没有整数\(x\)。K......
  • 题解:P9437 一棵树
    题目传送门明显的换根dp,感觉是道不错的换根dp练习题。题意一棵\(n\)个节点的树,点带权,定义\(w(x,y)=\overline{a_x\dotsa_y}\)。求\(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}w(i,j)\bmod998244353\)。思路我们不妨先求出\(i=1\)时的\(\sumw(i,j)\),再求\(......
  • [SDOI2012] 走迷宫 题解
    [SDOI2012]走迷宫题目描述Morenan被困在了一个迷宫里。迷宫可以视为\(n\)个点\(m\)条边的有向图,其中Morenan处于起点\(s\),迷宫的终点设为\(t\)。可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的有向边,到达另一个点。这样,Morenan走的步数可能......
  • 2024年暑期2024牛客暑期多校训练营1 C和H题解
    C题SumofSuffixSums题目大意:开始是给你一空数组,要经历q次操作,每次操作都会给出两个数字t和v,其中要从数组末尾去走元素t次,最后加上元素v。定义si=ai+ai+1+ai+2+ai+3+......+an,最后求s1+s2+s3+.......+sn的总和。最后答案注意取模。 题解:注意到sum的总和其实就......