【Atcoder】AGC022 B-F简要题解

一场咕咕咕了三天的AGC
可能我的智商不太适合做AGC?
可是立的flag总得完成!


*B.GCD Sequence

n = 3 n=3n=3不好构造,但是给了样例,直接输出即可。

为使全局gcd ⁡ = 1 \gcd=1gcd=1,构造任意个2的倍数,奇数个3的倍数即可。
总存在方案使得6 ∣ s u m 6|sum6sum
打表找出≤ 12 \leq 1212的长度为8 88的构造,每次整体+ 12 +12+12即可(注意分n nn的奇偶讨论)


C.Remainder Game

由于第k kk位操作的贡献是2 k 2^k2k,所以贪心从高到低诸位确定。
优化也不需要,暴力判即可。


*D.Shopping

求解最小化火车往返次数。

对于≥ 2 L \geq 2L2Lt i t_iti,直接t i   m o d   2 L t_i \ mod \ 2Lti mod 2L

此时所有t i &lt; 2 L t_i&lt;2Lti<2L,设l i = [ t i ≤ 2 x i ] , r i = [ t i ≤ 2 ( L − x i ) ] l_i=[t_i\leq 2x_i],r_i=[t_i\leq 2(L-x_i)]li=[ti2xi],ri=[ti2(Lxi)]分别表示点i ii能否直接右进右出/左进左出。

安排所有点按标号依次选择,逐步优化:
对于i &lt; j , l i = r j = 1 i&lt;j,l_i=r_j=1i<j,li=rj=1,可以先走j jj再从j → i j\to iji,贪心匹配最多即可。

注意讨论的细节:
code from wxh010910

#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;

template <typename T> inline void Read(T &x) {
  char c = getchar();
  bool f = false;
  for (x = 0; !isdigit(c); c = getchar()) {
    if (c == '-') {
      f = true;
    }
  }
  for (; isdigit(c); c = getchar()) {
    x = x * 10 + c - '0';
  }
  if (f) {
    x = -x;
  }
}

template <typename T> inline bool CheckMax(T &a, const T &b) {
  return a < b ? a = b, true : false;
}

template <typename T> inline bool CheckMin(T &a, const T &b) {
  return a > b ? a = b, true : false;
}

const int N = 300005;

int n, m, x, y, a[N];
bool l[N], r[N];
LL ans;

int main() {
#ifdef wxh010910
  freopen("d.in", "r", stdin);
#endif
  Read(n), Read(m);
  for (int i = 1; i <= n; ++i) {
    Read(a[i]);
  }
  for (int i = 1, t; i <= n; ++i) {
    Read(t);
    if (t % (m << 1) == 0) {
      ans += t;
    } else {
      ans += 1LL * (t / (m << 1) + 1) * (m << 1), t %= m << 1;
      if (t <= a[i] << 1) {
        l[i] = true;
      }
      if (t <= m - a[i] << 1) {
        r[i] = true;
      }
    }
  }
  for (int i = 1; i < n; ++i) {
    if (x && r[i]) {
      if (l[i]) {
        ++y;
      }
      --x, ans -= m << 1;
    } else if (!l[i] && r[i]) {
      if (y) {
        --y, ++x;
      }
    } else if (l[i]) {
      ++x;
    }
  }
  if (!r[n]) {
    ans += m << 1;
  }
  printf("%lld\n", ans);
#ifdef wxh010910
  Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
  return 0;
}

*E.Median Replace

设相邻第i ii个1和第i + 1 i+1i+1个1之间的0 00的个数为a i a_iai(包括首尾端点),分析如下:

  • 通过000 → 0 000\to 00000≥ 3 \geq 33a i a_iai不断− 2 -22,使得每个a i ∈ { 0 , 1 , 2 } a_i\in \{0,1,2\}ai{0,1,2}
  • 101 → 0 101\to 01010相当于可以直接删除a aa序列中的1 11,此时a aa序列由0 , 2 0,20,2构成。
  • 合并两个偶数(2或0)一定会变成奇数(1),再删去这个奇数,相当于序列中数可以两两抵消

若存在a p = a q = 0 , p &lt; q a_p=a_q=0,p&lt;qap=aq=0,p<qp pp为奇数,q qq为偶数,则可达目标状态:0 , 0 0,00,0

DP处理。

另:自动机解法


*F.Checkers

要被“显然”坑死了(智商捉急)
证明很不完善/严谨,欢迎指正(轻喷

一些明显的条件:

将答案看做X XX进制数,每一位上答案互不相关。问题转化为找合法的(由合法转移得到)X XX进制数的个数。

且系数均为+ 2 p / − 2 p +2^p/-2^p+2p/2p的形式,设第i ii位系数为p i p_ipi,则∑ i = 1 n p i = 1 \sum \limits_{i=1}^n p_i=1i=1npi=1。且p pp序列中1 11− 1 -11的总共出现次数为1 11,且若± 2 i ( i &gt; 0 ) \pm 2^i(i&gt;0)±2i(i>0)出现,± 2 i − 1 \pm 2^{i-1}±2i1必然出现(即系数在2的次幂上是连续的)。

最关键的条件(和命题充分必要):
对于任意i ii,可以通过调整绝对值为2 i 2^i2ip pp的符号使得绝对值≤ 2 i \leq 2^i2i的数和为1 11

考虑构造过程,必要性“显然”。
???这里就看不懂了。
经过我长久的思考(1天,我TCL),发现可以归纳法证明(???):
A AA满足,B BB满足,2 A − B 2A-B2AB的所有绝对值≤ 2 i \leq 2^i2i项相当于A AA中所有绝对值≤ 2 i − 1 \leq 2^{i-1}2i1的项(可以调整2 i − 1 2^{i-1}2i1的系数得到1 11,然后× 2 \times 2×2得到2 22)和B BB中所有绝对值≤ 2 i \leq 2^i2i的项,可以调整2 i 2^{i}2i的系数得到1,所以最终得到1。

充分性也可以归纳法证明(对于一个满足性质集合S SS,如果能分成2 A , − B 2A,-B2A,BA , B A,BA,B也满足这个条件,即得证):

不妨设− 1 ∈ S -1\in S1S(1 ∈ S 1\in S1S的情况类似),设k kk为最小的2 k ∈ S 2^k\in S2kS

  • 若对于1 ≤ i &lt; k 1\leq i&lt;k1i<k− 2 i -2^i2i都至少出现了两次,则可以构造A = { − 2 0 , − 2 1 , . . . , − 2 k − 2 , 2 k − 1 } A=\{-2^0,-2^1,...,-2^{k-2},2^{k-1}\}A={20,21,...,2k2,2k1}
    这里又“显然”了qwq,再来证明一下:
    2 A = { − 2 1 , − 2 2 , . . . , − 2 k − 1 , 2 k } 2A=\{-2^1,-2^2,...,-2^{k-1},2^{k}\}2A={21,22,...,2k1,2k}
    B = { 1 , a 1 2 1 , a 2 2 2 , . . . , a k − 1 2 k − 1 , a k 2 k , . . . } B=\{1,a_12^1,a_22^2,...,a_{k-1}2^{k-1},a_k2^k,...\}B={1,a121,a222,...,ak12k1,ak2k,...}
    S = { − 1 , − ( a 1 + 1 ) 2 1 , − ( a 2 + 1 ) 2 2 , . . . , − ( a k − 1 + 1 ) 2 k − 1 , ( 1 − a k ) 2 k , . . . } S=\{-1,-(a_1+1)2^1,-(a_2+1)2^2,...,-(a_{k-1}+1)2^{k-1},(1-a_k)2^k,...\}S={1,(a1+1)21,(a2+1)22,...,(ak1+1)2k1,(1ak)2k,...}
    a i + 1 ≥ 2 → a i ≥ 1 ( 1 ≤ i &lt; k ) , 1 − a k &gt; 1 → a k &lt; 0 a_i+1\geq 2\to a_i\geq 1(1\leq i&lt;k),1-a_k&gt;1\to a_k&lt;0ai+12ai1(1i<k),1ak>1ak<0
    S SS中,调整绝对值为2 i ( 0 ≤ i ≤ k ) 2^i(0\leq i\leq k)2i(0ik)项的系数得到1,而B BB中调整得到− 1 − 2 1 − 2 2 − . . . − 2 i − 1 ± 2 i -1-2^1-2^2-...-2^{i-1}\pm 2^i12122...2i1±2i2 i 2^i2i可以随意定符号,所以定成删去的那个是− 2 i -2^i2i即值+ 2 i +2^i+2i可以得到1。
    而对于i &gt; k i&gt;ki>k,设原本S SS的前缀和= s u m =sum=sum,则B BB的前缀和= − s u m − 2 1 − . . . − 2 k − 1 + 2 k = − s u m + 2 =-sum-2^1-...-2^{k-1}+2^k=-sum+2=sum21...2k1+2k=sum+2,设绝对值为2 i 2^i2i的项随意定符号后得到1 − s u m 1-sum1sum,同样可以系数取反得到s u m − 1 → s u m − 1 − s u m + 2 = 1 sum-1\to sum-1-sum+2=1sum1sum1sum+2=1,得证。
  • 否则记最小的只出现过一次的是− 2 i -2^i2i。如果i = 1 i=1i=1,那么B = { 0 } B=\{0\}B={0}满足条件;否则− 1 − 2 ∑ j &lt; i 2 j &lt; − 2 i − 1 -1-2\sum\limits_{j&lt;i}2^j&lt;-2^i-112j<i2j<2i1,无解。

考虑D P DPDP,设f [ i ] [ j ] f[i][j]f[i][j]表示前i ii个数,总和为1 + j V 1+jV1+jV的方案数,V VV表示当前枚举到的V = 2 k V=2^kV=2k项,V VV具体是多少不需要知道,预处理组合数n 4 n^4n4转移即可。


版权声明:本文为corsica6原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。