Codeforces Round #589 (Div. 2) 赛后反思

反思

总结而言:三思而后行永不言弃

赛前准备

  1. 刚换 parse-tool 没有熟悉,比赛的时候因为设置问题出了锅

  2. 没有调整好草稿本、桌面布局等

  3. 考试前应当适当小憩,但保持思维灵敏度

比赛过程

  1. A 题比较简单,但我在没想清楚时就开始写了,后来才发现我的 flag 设置反了

  2. 我在草稿本上列出了 B 题不成立的情况,但在后面的推导中麻证不成立会被后续判断给筛除,于是写的时候没有写这一部分,思路不是很清晰,导致思考后面如何包含浪费很多时间,WA了之后一直查代码原因,没有去思考思路是不是又问题,由于我不知道怎么操作的,在某次调整时把 h, w 直接搞反,检查和调整输入花了20分钟,直接心态爆炸

  3. C 题十分显然,然而我先是快速幂出锅,后是快速乘出锅,最后还有精度的问题,于是一直和答案对不上

  4. D 题性质很明显,然而我题目读错,以为需要不止 3 个集合,然后就死活想不出来

错误一览

  1. k <= log(n) / log(fac[i]) 改为 k <= log(n) / log(fac[i]) + eps

  2. 快速幂漏掉 if (y & 1)

    扫描二维码关注公众号,回复: 7401233 查看本文章

题解

1228B - Filling the Grid

注意在考虑竖排的填充时,由于是覆盖填充,每次填充前都必须要检查是否有违反情况
最后统计有多少可填可不填即可

#include <cstdio>
#include <algorithm>
 
const int mod = (int)1e9 + 7;
const int maxn = 1e3 + 10;
 
int c[maxn], r[maxn], map[maxn], w, h;
int m[maxn][maxn], v[maxn][maxn];
 
void qmul(int &x) {
  x = (x % mod) * 2 % mod;
}
 
signed main() {
  int ans = 1;
  scanf("%d %d", &h, &w);
  for (int i = 1; i <= h; ++ i) scanf("%d", &r[i]);
  for (int i = 1; i <= w; ++ i) scanf("%d", &c[i]);
  for (int i = 1; i <= h; ++ i) {
    for (int j = 1; j <= r[i]; ++ j) m[i][j] = 1, v[i][j] = 1;
    m[i][r[i] + 1] = 0, v[i][r[i] + 1] = 1;
  }
  for (int i = 1; i <= w; ++ i) {
    for (int j = 1; j <= c[i]; ++ j) {
      if (!m[j][i] && v[j][i]) return printf("0"), 0;
      m[j][i] = 1, v[j][i] = 1;
    }
    if (v[c[i] + 1][i] && m[c[i] + 1][i]) return printf("0"), 0;
    m[c[i] + 1][i] = 0, v[c[i] + 1][i] = 1;
  }
  for (int i = 1; i <= h; ++ i) {
    for (int j = 1; j <= w; ++ j) {
      if (!v[i][j]) qmul(ans);
    }
  }
  printf("%d", ans);
}

1228C - Primes and Multiplication

直接统计每一个底数对答案的贡献,细节在于对范围的思考

复杂度 \(O(x^{0.35}+loglogx⋅log{n})\)


#include <cmath>
#include <cstdio>
#include <algorithm>

const int maxn = 1e6 + 10;
const int modn = 1e9 + 7;

#define int long long
#define eps 1e-5

int p[maxn], n, m, t, c, fac[maxn], ans = 1;

inline void sieve() {
  for (int i = 2; i < maxn; ++ i) {
    if (!p[i]) p[++t] = i;
    for (int j = 1; j <= t && p[j] * i < maxn; ++ j) {
      p[p[j] * i] = 1; if (i % p[j] == 0) break;
    }
  }
}

inline int qpow(int x, int y, int mod) {
  int res = 1 % mod; x %= mod;
  for (; y; y >>= 1, x = x * x % mod)
    if (y & 1) res = res * x % mod;
  return res;
}

signed main() {
  scanf("%lld %lld", &m, &n); sieve(); 
  for (int i = 1; i <= t; ++ i) {
    if (m % p[i] == 0) fac[++c] = p[i];
    while (m % p[i] == 0) m /= p[i];
  }
  if (m != 1) fac[++c] = m;
  for (int i = 1; i <= c; ++ i) {
    int num = 0;
    for (int k = 1; k <= log(n) / log(fac[i]) + eps; ++ k)
      num += (int)(n / pow(fac[i], k));
    ans = ans * qpow(fac[i], num, modn) % modn;
  }
  printf("%lld", ans);
}

1228D - Complete Tripartite

\(x, y\) 有边直接相连,则记 \([x, y] = 1\) 反之为 \(0\)

易知此图有:若 \([x, y] = 1\),则一定在不同集合;反之,则一定在不同集合

因此我们可以先将不直接相连的点先分到同一组,下面我们只需要验证此分发能否满足 \(\forall x \in v_i, y \in v_j [x, y] = 1\)

显然我们不能对每个点进行搜索判断是否满足,复杂度将达到 \(O(n^2)\)

不难发现,这种情况下 \(m = |v1|⋅|v2|+|v2|⋅|v3|+|v3|⋅|v1|\)

猜你喜欢

转载自www.cnblogs.com/alessandrochen/p/11614482.html
今日推荐