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;
}

浙公网安备 33010602011771号