CodeForces Gym 101669 简要题解

Concerts

f(i,j) f ( i , j ) 表示最后一次匹配的位置 i ≤ i ,匹配了 j j 个位置的方案数。

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;
const int M = 305;
const int mod = 1e9 + 7;

int n, m, wait[M], f[N][M];
char s[N], t[M];

int add(int x, int y) {
  x += y;
  if (x >= mod) {
    x -= mod;
  }
  return x;
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d %d", &m, &n);
  for (int i = 0; i < 26; ++i) {
    scanf("%d", &wait[i]);
  }
  scanf("%s%s", t + 1, s + 1);
  f[0][0] = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j <= m; ++j) {
      f[i][j] = f[i - 1][j];
      if (s[i] == t[j]) {
        if (j == 1) {
          f[i][j] = add(f[i][j], f[i - 1][j - 1]);
        } else {
          int k = i - wait[t[j - 1] - 'A'] - 1;
          if (k >= 0) {
            f[i][j] = add(f[i][j], f[k][j - 1]);
          }
        }
      }
    }
  }
  printf("%d\n", f[n][m]);
  return 0;
}

Bricks

不难发现砖块掉落的顺序不影响最后答案,枚举空位进行DP转移,那么就是要区间长度和区间内砖块个数相等。

#include <bits/stdc++.h>

using namespace std;

const int N = 1100005;
const int mod = 1e9 + 7;

int n, m, f[N], g[N], s[N];

int add(int x, int y) {
  x += y;
  if (x >= mod) {
    x -= mod;
  }
  return x;
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d %d", &n, &m);
  ++n;
  while (m--) {
    int x;
    scanf("%d", &x);
    ++s[x];
  }
  for (int i = 1; i <= n; ++i) {
    s[i] += s[i - 1];
  }
  g[n] = 1;
  for (int i = 1; i <= n; ++i) {
    if (s[i] == s[i - 1]) {
      f[i] = g[s[i - 1] - (i - 1) + n];
      g[s[i] - i + n] = add(g[s[i] - i + n], f[i]);
    }
  }
  printf("%d\n", f[n]);
  return 0;
}

Christmas Tree

对每种颜色求出它的极长链,那么相当于要给颜色定一个拓扑序,用倍增优化连边即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;
const int M = 17;
const int S = 2000005;

int n, m, total, color[N], depth[N], answer_x[N], answer_y[N], degree[S], id[M][N], anc[M][N];
vector<int> adj[N], nodes[N], to[S];

void dfs(int x) {
  for (int i = 1; i < M; ++i) {
    anc[i][x] = anc[i - 1][anc[i - 1][x]];
  }
  for (auto y : adj[x]) {
    if (y != anc[0][x]) {
      anc[0][y] = x;
      depth[y] = depth[x] + 1;
      dfs(y);
    }
  }
}

int jump(int x, int d) {
  for (int i = 0; i < M; ++i) {
    if (d >> i & 1) {
      x = anc[i][x];
    }
  }
  return x;
}

int lca(int x, int y) {
  if (depth[x] > depth[y]) {
    x = jump(x, depth[x] - depth[y]);
  } else if (depth[x] < depth[y]) {
    y = jump(y, depth[y] - depth[x]);
  }
  if (x == y) {
    return x;
  }
  for (int i = M - 1; ~i; --i) {
    if (anc[i][x] != anc[i][y]) {
      x = anc[i][x];
      y = anc[i][y];
    }
  }
  return anc[0][x];
}

int dist(int x, int y) {
  return depth[x] + depth[y] - (depth[lca(x, y)] << 1);
}

int find(int x, int y, int z, int d) {
  if (d <= depth[x] - depth[z]) {
    return jump(x, d);
  } else {
    return jump(y, depth[x] + depth[y] - (depth[z] << 1) - d);
  }
}

void add_edge(int color, int x, int y) {
  if (depth[x] < depth[y]) {
    swap(x, y);
  }
  if (depth[x] > depth[y]) {
    for (int i = 0; i < M; ++i) {
      if (depth[x] - depth[y] >> i & 1) {
        to[color].push_back(id[i][x]);
        x = anc[i][x];
      }
    }
  }
  if (x == y) {
    to[color].push_back(id[0][x]);
    return;
  }
  for (int i = M - 1; ~i; --i) {
    if (anc[i][x] != anc[i][y]) {
      to[color].push_back(id[i][x]);
      to[color].push_back(id[i][y]);
      x = anc[i][x];
      y = anc[i][y];
    }
  }
  to[color].push_back(id[0][x]);
  to[color].push_back(id[0][y]);
  to[color].push_back(id[0][anc[0][x]]);
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &color[i]);
    nodes[color[i]].push_back(i);
  }
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
  dfs(1);
  total = m;
  for (int i = 0; i < M; ++i) {
    for (int j = 1; j <= n; ++j) {
      id[i][j] = ++total;
    }
  }
  for (int i = 1; i <= n; ++i) {
    to[id[0][i]].push_back(color[i]);
  }
  for (int i = 1; i < M; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (anc[i - 1][j]) {
        to[id[i][j]].push_back(id[i - 1][j]);
        to[id[i][j]].push_back(id[i - 1][anc[i - 1][j]]);
      }
    }
  }
  for (int i = 1; i <= m; ++i) {
    if (nodes[i].empty()) {
      printf("%d 1 1\n", i);
      continue;
    }
    int x = nodes[i][0], y = nodes[i][0], diameter = 0;
    for (int j = 1; j < nodes[i].size(); ++j) {
      int z = nodes[i][j], d, type = 0;
      d = dist(x, z);
      if (d > diameter) {
        diameter = d;
        type = 1;
      }
      d = dist(y, z);
      if (d > diameter) {
        diameter = d;
        type = 2;
      }
      if (type == 1) {
        y = z;
      } else if (type == 2) {
        x = z;
      }
    }
    answer_x[i] = x;
    answer_y[i] = y;
    int z = lca(x, y);
    vector<pair<int, int>> all;
    for (auto p : nodes[i]) {
      all.push_back(make_pair(dist(x, p), p));
    }
    sort(all.begin(), all.end());
    for (int j = 1; j < all.size(); ++j) {
      if (all[j].first != all[j - 1].first + 1) {
        int u = find(x, y, z, all[j].first - 1), v = find(x, y, z, all[j - 1].first + 1);
        add_edge(i, u, v);
      }
    }
  }
  for (int x = 1; x <= total; ++x) {
    for (auto y : to[x]) {
      ++degree[y];
    }
  }
  queue<int> q;
  for (int i = 1; i <= total; ++i) {
    if (!degree[i]) {
      q.push(i);
    }
  }
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    if (x <= m && !nodes[x].empty()) {
      printf("%d %d %d\n", x, answer_x[x], answer_y[x]);
    }
    for (auto y : to[x]) {
      if (!--degree[y]) {
        q.push(y);
      }
    }
  }
  return 0;
}

Harry Potter and The Vector Spell

将每个向量的两个 1 连一条边,对于一个连通块,它的贡献是它的大小减 1 1

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

int n, m, f[N], size[N];
vector<int> a[N];

int find(int x) {
  while (x != f[x]) {
    x = f[x] = f[f[x]];
  }
  return x;
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d %d", &m, &n);
  for (int i = 1; i <= m; ++i) {
    int k;
    scanf("%d", &k);
    while (k--) {
      int x;
      scanf("%d", &x);
      a[x].push_back(i);
    }
    f[i] = i;
  }
  for (int i = 1; i <= n; ++i) {
    f[find(a[i][0])] = find(a[i][1]);
  }
  for (int i = 1; i <= m; ++i) {
    ++size[find(i)];
  }
  int answer = 0;
  for (int i = 1; i <= m; ++i) {
    if (size[i]) {
      answer += size[i] - 1;
    }
  }
  printf("%d\n", answer);
  return 0;
}

Looping Playlist

预处理每种状态是否合法,枚举开头结尾接起来的那一段是哪种调,然后贪心即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 10000005;

map<string, int> f;
int n, a[N];
bool ok[N];

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(0);
  cin.tie(0);
  f["Do"] = 0;
  f["Do#"] = 1;
  f["Re"] = 2;
  f["Re#"] = 3;
  f["Mi"] = 4;
  f["Fa"] = 5;
  f["Fa#"] = 6;
  f["Sol"] = 7;
  f["Sol#"] = 8;
  f["La"] = 9;
  f["La#"] = 10;
  f["Si"] = 11;
  for (int i = 0; i < 12; ++i) {
    int s = 0;
    s |= 1 << (i + 0) % 12;
    s |= 1 << (i + 2) % 12;
    s |= 1 << (i + 4) % 12;
    s |= 1 << (i + 5) % 12;
    s |= 1 << (i + 7) % 12;
    s |= 1 << (i + 9) % 12;
    s |= 1 << (i + 11) % 12;
    ok[s] = true;
  }
  for (int i = 1; i < 1 << 12; i <<= 1) {
    for (int j = 0; j < 1 << 12; j += i << 1) {
      for (int k = 0; k < i; ++k) {
        ok[j + k] |= ok[j + k + i];
      }
    }
  }
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    string s;
    cin >> s;
    a[i] = f[s];
  }
  int answer = n;
  for (int i = 0; i < 12; ++i) {
    int s = 0;
    s |= 1 << (i + 0) % 12;
    s |= 1 << (i + 2) % 12;
    s |= 1 << (i + 4) % 12;
    s |= 1 << (i + 5) % 12;
    s |= 1 << (i + 7) % 12;
    s |= 1 << (i + 9) % 12;
    s |= 1 << (i + 11) % 12;
    int l = 1, r = n;
    while (l <= n && (s >> a[l] & 1)) {
      ++l;
    }
    while (r && (s >> a[r] & 1)) {
      --r;
    }
    int result = 1, state = (1 << 12) - 1;
    for (int j = l; j <= r; ++j) {
      if (!ok[state | 1 << a[j]]) {
        state = 1 << a[j];
        ++result;
      } else {
        state |= 1 << a[j];
      }
    }
    answer = min(answer, result);
  }
  printf("%d\n", answer);
  return 0;
}

Binary Transformations

肯定是先把按照 c 从大到小的顺序把 1 1 变成 0 ,再按照从小到大的顺序把 0 0 变成 1 。注意一开始可以将一些 1 1 先变成 0 再变成 1 1 ,枚举变了前多少大的计算即可。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 5005;

pair<int, int> all[N];
char s[N], t[N];
int n, a[N];
bool use[N];

ll solve() {
  ll result = 0, sum = 0;
  for (int i = 1; i <= n; ++i) {
    if (s[i] == '1') {
      sum += a[i];
    }
  }
  for (int i = n; i; --i) {
    int x = all[i].second;
    if (use[x] || (s[x] == '1' && t[x] == '0')) {
      sum -= a[x];
      result += sum;
    }
  }
  for (int i = 1; i <= n; ++i) {
    int x = all[i].second;
    if (use[x] || (s[x] == '0' && t[x] == '1')) {
      sum += a[x];
      result += sum;
    }
  }
  return result;
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    all[i] = make_pair(a[i], i);
  }
  sort(all + 1, all + n + 1);
  scanf("%s %s", s + 1, t + 1);
  vector<pair<int, int>> to_change;
  for (int i = 1; i <= n; ++i) {
    if (s[i] == '1' && t[i] == '1') {
      to_change.push_back(make_pair(-a[i], i));
    }
  }
  sort(to_change.begin(), to_change.end());
  ll answer = solve();
  for (auto p : to_change) {
    use[p.second] = true;
    answer = min(answer, solve());
  }
  printf("%lld\n", answer);
  return 0;
}

Robots

模拟。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll solve(vector<pair<ll, ll>> a) {
  ll v = 0, result = 0;
  for (auto p : a) {
    result += 2ll * v * p.second + p.first * p.second * p.second;
    v += p.first * p.second;
  }
  return result;
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  int n;
  scanf("%d", &n);
  vector<pair<ll, ll>> a(n);
  for (int i = 0; i < n; ++i) {
    scanf("%lld %lld", &a[i].first, &a[i].second);
  }
  ll answer = -solve(a);
  sort(a.begin(), a.end());
  reverse(a.begin(), a.end());
  answer += solve(a);
  printf("%lld.%d\n", answer >> 1, answer & 1 ? 5 : 0);
  return 0;
}

Cat and Mouse

考虑如果猫和老鼠在相邻的边上了,老鼠先走,那么猫有两种策略:

  • 顺着怼过去。

  • 老鼠走一步,猫停留,老鼠走回来(必须回来不然不优),猫和老鼠走到一个点上,老鼠走一步,猫跟上,老鼠走一步,猫不动(相当于用 4 步的代价堵住老鼠要往复的边,老鼠位置不变)。

    将每条边 (mouse,cat) ( m o u s e , c a t ) 作为状态预处理到终止态的最短路,然后枚举老鼠走了几步之后猫开始堵住老鼠,可以通过预处理每个点的深度来知道猫是否能到达,之后就用预处理好的最短路来计算答案。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 100005;
    const int inf = 0x3f3f3f3f;
    
    int n, mouse, dist[N], depth[N];
    vector<pair<int, int>> edges, to[N];
    vector<int> adj[N], pool[N << 2];
    
    void dfs(int x, int parent) {
      for (auto y : adj[x]) {
        if (y != parent) {
          depth[y] = depth[x] + 1;
          dfs(y, x);
        }
      }
    }
    
    int get_id(int x, int y) {
      return lower_bound(edges.begin(), edges.end(), make_pair(x, y)) - edges.begin();
    }
    
    int find_next(int x, int ban) {
      for (auto y : adj[x]) {
        if (y != ban) {
          return y;
        }
      }
      return -1;
    }
    
    int main() {
    #ifdef wxh010910
      freopen("input.txt", "r", stdin);
    #endif
      int T;
      scanf("%d", &T);
      while (T--) {
        scanf("%d %d", &n, &mouse);
        --mouse;
        for (int i = 0; i < n; ++i) {
          adj[i].clear();
        }
        edges.clear();
        for (int i = 0; i < n - 1; ++i) {
          int x, y;
          scanf("%d %d", &x, &y);
          --x;
          --y;
          adj[x].push_back(y);
          adj[y].push_back(x);
          edges.push_back(make_pair(x, y));
          edges.push_back(make_pair(y, x));
        }
        sort(edges.begin(), edges.end());
        for (int i = 0; i < n; ++i) {
          reverse(adj[i].begin(), adj[i].end());
        }
        if (!~find_next(mouse, -1)) {
          puts("0");
          continue;
        }
        dfs(0, -1);
        for (int i = 0; i < n << 2; ++i) {
          pool[i].clear();
        }
        for (int i = 0; i < edges.size(); ++i) {
          dist[i] = inf;
          to[i].clear();
        }
        for (int i = 0; i < edges.size(); ++i) {
          int x = edges[i].first, y = edges[i].second, z = find_next(x, y);
          if (!~z) {
            dist[i] = 0;
            pool[0].push_back(i);
          } else {
            to[get_id(z, x)].push_back(make_pair(i, 1));
            if (find_next(z, -1) == x) {
              to[get_id(x, z)].push_back(make_pair(i, 4));
            }
          }
        }
        for (int i = 0; i < n << 2; ++i) {
          for (auto x : pool[i]) {
            if (dist[x] == i) {
              for (auto e : to[x]) {
                if (dist[e.first] > i + e.second) {
                  dist[e.first] = i + e.second;
                  pool[i + e.second].push_back(e.first);
                }
              }
            }
          }
        }
        int answer = inf, current = mouse;
        for (int i = 0; i < n; ++i) {
          int next = find_next(current, i ? -1 : 0);
          if (depth[next] < i || (depth[next] == i && depth[current] != i - 1)) {
            answer = min(answer, i + dist[get_id(current, next)]);
          }
          current = next;
        }
        printf("%d\n", answer);
      }
      return 0;
    }

    Tetris

    状态不多,记忆化搜索,碰到栈中的元素答案就是 1 − 1

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 55;
    const char s[3][N] = {
    "010111110011110010010010011001",
    "111100011010010010111011111111",
    "010100001110011111011110110110"
    };
    
    map<int, int> mem[N], visit[N];
    int n, a[N];
    
    int go(int state, int type, int rotate) {
      if (state >> 21) {
        return -1;
      }
      char b[3][3];
      if (!rotate) {
        for (int i = 0; i < 3; ++i) {
          for (int j = 0; j < 3; ++j) {
            b[i][j] = s[i][j + type * 3];
          }
        }
      } else if (rotate == 1) {
        for (int i = 0; i < 3; ++i) {
          for (int j = 0; j < 3; ++j) {
            b[i][j] = s[j][2 - i + type * 3];
          }
        }
      } else if (rotate == 2) {
        for (int i = 0; i < 3; ++i) {
          for (int j = 0; j < 3; ++j) {
            b[i][j] = s[2 - i][2 - j + type * 3];
          }
        }
      } else {
        for (int i = 0; i < 3; ++i) {
          for (int j = 0; j < 3; ++j) {
            b[i][j] = s[2 - j][i + type * 3];
          }
        }
      }
      int p = 7;
      for (int i = 6; ~i; --i) {
        bool flag = false;
        for (int j = 0; j < 3; ++j) {
          for (int k = 0; k < 3; ++k) {
            if (b[j][k] == '1' && (state >> (i + j) * 3 + k & 1)) {
              flag = true;
            }
          }
        }
        if (flag) {
          break;
        }
        p = i;
      }
      int new_state = state;
      for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
          if (b[i][j] == '1') {
            new_state |= 1 << (i + p) * 3 + j;
          }
        }
      }
      for (int i = 0; i < 10; ++i) {
        while ((new_state >> i * 3 & 7) == 7) {
          new_state = (new_state & (1 << 3 * i) - 1) | (new_state >> (i + 1) * 3 << i * 3);
        }
      }
      return new_state;
    }
    
    int dfs(int state, int x) {
      if (visit[x][state] == 1) {
        return -1;
      }
      if (visit[x][state] == 2) {
        return mem[x][state];
      }
      visit[x][state] = 1;
      int result = 0;
      for (int i = 0; i < 4; ++i) {
        int next = go(state, a[x], i);
        if (~next) {
          int value = dfs(next, (x + 1) % n);
          if (!~value) {
            return -1;
          }
          result = max(result, value + 1);
        }
      }
      visit[x][state] = 2;
      mem[x][state] = result;
      return result;
    }
    
    int main() {
    #ifdef wxh010910
      freopen("input.txt", "r", stdin);
    #endif
      scanf("%d", &n);
      for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
      }
      printf("%d\n", dfs(0, 0));
      return 0;
    }

    Cunning Friends

    打表找规律。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
    #ifdef wxh010910
      freopen("input.txt", "r", stdin);
    #endif
      int n, one = 0, two = 0, three = 0;
      scanf("%d", &n);
      if (n == 1) {
        puts("Win");
        return 0;
      }
      while (n--) {
        int x;
        scanf("%d", &x);
        if (x == 1) {
          ++one;
        } else if (x == 2) {
          ++two;
        } else {
          ++three;
        }
      }
      if (three > 1 || two > 2 || three + two == 3) {
        puts("Lose");
        return 0;
      }
      if (three + two == 1 || one % 3) {
        puts("Win");
      } else {
        puts("Lose");
      }
      return 0;
    }

    Escape Room

    考虑 Ai=1 A i = 1 的,显然我们会顺着放 N,N1,N2, N , N − 1 , N − 2 , ⋯ 然后开始放 Ai=2 A i = 2 的。排序即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
    #ifdef wxh010910
      freopen("input.txt", "r", stdin);
    #endif
      int n;
      scanf("%d", &n);
      vector<pair<int, int>> a(n);
      for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i].first);
        a[i].second = i;
      }
      sort(a.begin(), a.end(), greater<pair<int, int>> ());
      vector<int> answer(n);
      for (int i = 0; i < n; ++i) {
        answer[a[i].second] = i;
      }
      for (int i = 0; i < n; ++i) {
        printf("%d%c", answer[i] + 1, i == n - 1 ? '\n' : ' ');
      }
      return 0;
    }

    Divide and Conquer

    因为总边数是 4(n1) 4 ( n − 1 ) ,所以一定有一个点度数不超过 3 3 ,所以答案不超过 3 。所以有一棵树一定只断了一条边,那么在另一棵树中,如果一条边两端连接的两个点在第一棵树中是不同的连通块,那么这条边就要割掉。用 dsu on tree 统计即可。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 100005;
    
    pair<int, int> result;
    int n, current;
    bool color[N];
    
    struct tree_t {
      int son[N], size[N];
      vector<int> adj[N];
    
      void dfs(int x, int parent) {
        size[x] = 1;
        for (auto y : adj[x]) {
          if (y != parent) {
            dfs(y, x);
            size[x] += size[y];
            if (size[y] > size[son[x]]) {
              son[x] = y;
            }
          }
        }
      }
    } a, b;
    
    void flip(int x, tree_t &a) {
      for (auto y : a.adj[x]) {
        if (color[y] == color[x]) {
          ++current;
        } else {
          --current;
        }
      }
      color[x] = !color[x];
    }
    
    void modify(int x, int parent, tree_t &a, tree_t &b) {
      flip(x, b);
      for (auto y : a.adj[x]) {
        if (y != parent) {
          modify(y, x, a, b);
        }
      }
    }
    
    void dfs(int x, int parent, bool keep, tree_t &a, tree_t &b) {
      for (auto y : a.adj[x]) {
        if (y != parent && y != a.son[x]) {
          dfs(y, x, false, a, b);
        }
      }
      if (a.son[x]) {
        dfs(a.son[x], x, true, a, b);
      }
      for (auto y : a.adj[x]) {
        if (y != parent && y != a.son[x]) {
          modify(y, x, a, b);
        }
      }
      flip(x, b);
      if (parent) {
        if (current < result.first) {
          result = make_pair(current, 0);
        }
        if (current == result.first) {
          ++result.second;
        }
      }
      if (!keep) {
        modify(x, parent, a, b);
      }
    }
    
    pair<int, int> solve(tree_t &a, tree_t &b) {
      a.dfs(1, 0);
      result = make_pair(n, 0);
      dfs(1, 0, false, a, b);
      ++result.first;
    }
    
    int main() {
    #ifdef wxh010910
      freopen("input.txt", "r", stdin);
    #endif
      scanf("%d", &n);
      for (int i = 1; i < n; ++i) {
        int x, y;
        scanf("%d %d", &x, &y);
        a.adj[x].push_back(y);
        a.adj[y].push_back(x);
      }
      for (int i = 1; i < n; ++i) {
        int x, y;
        scanf("%d %d", &x, &y);
        b.adj[x].push_back(y);
        b.adj[y].push_back(x);
      }
      solve(a, b);
      if (result.first == 2) {
        printf("2 %d\n", result.second);
        return 0;
      }
      int answer = 0;
      if (result.first == 3) {
        answer += result.second;
      }
      solve(b, a);
      if (result.first == 3) {
        answer += result.second;
      }
      printf("3 %d\n", answer);
      return 0;
    }
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值