ABC412

D - Make 2-Regular Graph

考虑排列的性质

将排列对应的下标与值分别连边,发现会生成有若干环的图

此时恰好每个点入度为2

去掉重边自环的情况,计算答案取min

Code

#include <bits/stdc++.h>
using namespace std;
int n, m, p[10], ans = 666;
bool G[10][10], vis[10], T[10][10];
void dfs(int k) {
  // 生成排列的第 k 位
  if(k > n) { // 生成结束了
    int res = 0;
    memset(T, false, sizeof(T));
    for(int i = 1; i <= n; i++) T[i][p[i]] = T[p[i]][i] = true;
    for(int i = 1; i <= n; i++) {
      for(int j = 1; j < i; j++) {
        res += T[i][j] ^ G[i][j];
        // 0^0 = 0, 1^1 = 0
        // 1^0 = 1, 0^1 = 1
      }
    }
    ans = min(ans, res);
    return;
  }
  for(int i = 1; i <= n; i++) {
    if(!vis[i] && k != i && (i >= k || p[i] != k)) {
      vis[i] = true;
      p[k] = i;
      dfs(k + 1);
      vis[i] = false; // 回溯
    }
  }
}
int main() {
  scanf("%d %d", &n, &m);
  for(int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    G[u][v] = G[v][u] = true; // 邻接表
  }
  dfs(1);
  printf("%d\n", ans);
  return 0;
}

注:排列有很多性质

E - LCM Sequence

考虑答案来源2部分

第一种是p^k(p为质数,k>=2)

第二种是p,质数本身

因为区间差<=1e7

做一个区间筛

区间偏移一下即可

Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e7 + 5;
bool npr[N]; // Not Prime
bool vis[N];
signed main() {
  int l, r, ans = 0;
  scanf("%lld %lld", &l, &r);
  // 埃
  for(int i = 2; i < N; i++) {
    if(!npr[i]) { // i 是素数
      // 筛掉所有 [L+1, R] 当中的 i 的倍数
      for(int j = (l / i + 1) * i; j <= r; j += i) {
        vis[j - l] = true; // vis[x] 记录的实际上是 (x + l) 这个数的信息
        // 第一部分答案,p^k (k >= 2)
        int cur = j;
        while(cur % i == 0) cur /= i;
        if(cur == 1) ans++;
      }
      
      // 筛掉所有 < N 的 i 的倍数
      for(int j = i * 2; j < N; j += i) {
        npr[j] = true;
      }
    }
  }
  // 第二部分答案,p,如果 vis = false 就把答案+1
  for(int i = l; i <= r; i++) ans += !vis[i - l];
  printf("%lld\n", ans);
  return 0;
}
posted @ 2025-06-29 20:21  gbrrain  阅读(52)  评论(0)    收藏  举报