【Atcoder】AGC026 B-F简要题解

**B.rng_10s

特判 A < B A<B A<B D < B D<B D<B的情况。

问题转化为初始坐标为 A − B A-B AB,每次可以移动 − B -B B + D − B +D-B +DB,要求点始终落在 [ C − B + 1 , C − B + D ] [C-B+1,C-B+D] [CB+1,CB+D]中。
发现可达坐标在模 gcd ⁡ ( B , D ) \gcd(B,D) gcd(B,D)意义下与 A A A同余,那么找到最小的一个 x ≡ A ( m o d gcd ⁡ ( B , D ) ) x\equiv A\pmod {\gcd(B,D)} xA(modgcd(B,D)) x ≥ C − B + 1 x\geq C-B+1 xCB+1的数, x ≥ 0 x\geq 0 x0则输出"Yes",否则输出"No"。

p.s 具体实现时,可以直接找到第一个 < 0 <0 <0 x x x,判断其是否 ≥ C − B + 1 \geq C-B+1 CB+1


C.String Coloring

2 n , n ≤ 18 2n,n\leq 18 2n,n18,明示折半枚举

2 n 2^n 2n枚举前 n n n个字符的颜色,两个串的具体值都能够被确定, 然后 n 2 n^2 n2DP求出后 n n n个字符颜色匹配的方案数即可。


*D.Histogram Coloring

一开始 1 0 9 10^9 109还以为是矩阵快速幂什么的,好zz。。。

考虑相邻两行(假设列数相同),它们要么对应位置颜色都相同(两行都是颜色交错的),要么都全部不同。按高度 D P DP DP即可。

pair<int, int> solve(int l, int r, int base, vector<int> &a) {
  int x = *min_element(a.begin() + l, a.begin() + r), coef = 1, all = 1, number = 0;
  for (int i = l; i < r; ++i) {
    if (a[i] != x) {
      int j = i;
      while (j + 1 < r && a[j + 1] != x) {
        ++j;
      }
      pair<int, int> value = solve(i, j + 1, x, a);
      i = j;
      coef = mul(coef, value.first);
      all = mul(all, add(value.first, value.second));
    } else {
      ++number;
    }
  }
  return make_pair(mul(coef, power(2, x - base)), add(mul(all, power(2, number)), mul(coef, sub(power(2, x - base), 2))));
}

//ans=solve(0, n, 0, a).second

*E.Synchronized Subsequence

设第 i i i a a a的位置为 a i a_i ai,第 i i i b b b的位置为 b i b_i bi
可以把序列分成若干个极小段,满足每段内 c n t a = c n t b cnt_a=cnt_b cnta=cntb,且所有 a i < b i a_i<b_i ai<bi或所有 a i > b i a_i>b_i ai>bi

a i < b i a_i<b_i ai<bi,这一段的最优解必然形如 a b a b a b . . . ababab... ababab...(去掉其中连续的 a a a)
a i > b i a_i>b_i ai>bi,这一段的最优解必然是一段后缀。

若选择了某段,必然选择了这段的最优解,所以求出每段最优解后 d p dp dp即可


*F.Manju Game

考虑先手第一次从序列中间选择了一个格子,将序列分成了左右两部分,则接下来的操作必然是从当前位置出发向左/右交替选完,只剩下另一部分。

设奇数格子的 ∑ a i = A \sum a_i=A ai=A,偶数格子的 ∑ a i = B \sum a_i=B ai=B

  • n n n为偶数。若先手从中间选了一个格子,剩下的格子必然分成了一个奇数段和一个偶数段,后手选择偶数段往下走,到奇数段时就变成了后手可以先决策,答案不会比先手一开始选定一种奇偶性的格子走更优。所以 n n n为偶数时的先手答案为 max ⁡ ( A , B ) \max(A,B) max(A,B)
  • n n n为奇数。若先手选择了一个偶数格子,剩下的格子必然分成了两个奇数段,后手任意去掉一边后转成了另一边的子问题;否则先手选择了一个奇数格子,能保证的最优答案为 A A A
    可以将每次选择的偶数格子看做关键点,最终序列会被这些关键点划分成若干段,且有且仅有一段,先手选择了其中所有奇数格子,其它段先手都选择了其中偶数格子。先手的答案就是关键点加上每段选择的值的和。
    先手可以决策出段的划分:构造一个决策二叉树,每次往后手选择的另一侧走;后手可以决策出哪一段先手选择奇数格子:控制在决策二叉树上向下走的路线。
    考虑二分答案 m i d mid mid,判断先手的答案是否 ≥ B + m i d \geq B+mid B+mid,相当于判断是否存在一种划分方式,使得每一段中奇数格子值-偶数格子值 ≥ m i d \geq mid mid
    贪心判断即可。

你可能感兴趣的:(妙,atcoder)