【Atcoder】AGC022 B-F简要题解

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


*B.GCD Sequence

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

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


C.Remainder Game

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


*D.Shopping

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

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

此时所有 t i < 2 L t_i<2L ti<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 i i能否直接右进右出/左进左出。

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

注意讨论的细节:
code from wxh010910

#include 

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 i i个1和第 i + 1 i+1 i+1个1之间的 0 0 0的个数为 a i a_i ai(包括首尾端点),分析如下:

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

若存在 a p = a q = 0 , p < q a_p=a_q=0,p<q ap=aq=0,p<q p p p为奇数, q q q为偶数,则可达目标状态: 0 , 0 0,0 0,0

DP处理。

另:自动机解法


*F.Checkers

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

一些明显的条件:

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

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

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

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

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

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

  • 若对于 1 ≤ i < k 1\leq i<k 1i<k − 2 i -2^i 2i都至少出现了两次,则可以构造 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 < k ) , 1 − a k > 1 → a k < 0 a_i+1\geq 2\to a_i\geq 1(1\leq i<k),1-a_k>1\to a_k<0 ai+12ai1(1i<k),1ak>1ak<0
    S S S中,调整绝对值为 2 i ( 0 ≤ i ≤ k ) 2^i(0\leq i\leq k) 2i(0ik)项的系数得到1,而 B B B中调整得到 − 1 − 2 1 − 2 2 − . . . − 2 i − 1 ± 2 i -1-2^1-2^2-...-2^{i-1}\pm 2^i 12122...2i1±2i 2 i 2^i 2i可以随意定符号,所以定成删去的那个是 − 2 i -2^i 2i即值 + 2 i +2^i +2i可以得到1。
    而对于 i > k i>k i>k,设原本 S S S的前缀和 = s u m =sum =sum,则 B B B的前缀和 = − 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^i 2i的项随意定符号后得到 1 − s u m 1-sum 1sum,同样可以系数取反得到 s u m − 1 → s u m − 1 − s u m + 2 = 1 sum-1\to sum-1-sum+2=1 sum1sum1sum+2=1,得证。
  • 否则记最小的只出现过一次的是 − 2 i -2^i 2i。如果 i = 1 i=1 i=1,那么 B = { 0 } B=\{0\} B={0}满足条件;否则 − 1 − 2 ∑ j < i 2 j < − 2 i − 1 -1-2\sum\limits_{j<i}2^j<-2^i-1 12j<i2j<2i1,无解。

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

你可能感兴趣的:(妙,结论及推导,概率与期望,贪心,构造,atcoder)