A - Square Inequality
水题
B - Intersection
水题,就是找公共区间,维护一下 Lmax,Rmin即可
void solve() {int n, a, b;int maxa = -1, minb = 0x3f3f3f3f;cin >> n;for (int i = 0; i < n; ++i) {cin >> a;maxa = max(maxa, a);}for (int i = 0; i < n; ++i) {cin >> b;minb = min(minb, b);}cout << (minb - maxa + 1 > 0 ? minb - maxa + 1 : 0);}
C - IPFL
交换两个或者把前一半和后一半交换,求
次变换后的结果。
模拟会T,把字符串前后两个分开存,然后进行操作
void solve() {string s, x, y;int n, q, a, b, op;cin >> n >> s >> q;x = s.substr(0, n), y = s.substr(n, n);while (q--) {cin >> op >> a >> b;if (op == 2) swap(x, y);else {a--, b--;if (a > b) swap(a, b);if (b < n) swap(x[a], x[b]);else if (a >= n)swap(y[a - n], y[b - n]);elseswap(x[a], y[b - n]);}}cout << x << y;}
D - RGB Coloring 2
个点
条边的无向图,求用三种颜色染色后每条边相连的点不同的图有几种。
一看数据范围显然是一个搜索题,不过直接搜索会有一些问题,因为先搜到哪个的不同可能图染色后是相同的,会造成重复,既然如此,那我们随便指定一个顺序就可以了。
using ll = long long;const int N = 30;vector<int> e[N], a;int col[N], v[N][4];ll ans = 1, cur;bool vis[N];void dfs0(int x) {a.push_back(x);vis[x] = true;for (int &y : e[x])if (!vis[y]) dfs0(y);}void dfs(int x) {if (x == a.size()) {cur++;return;}for (int i = 1; i <= 3; ++i) {if (!v[a[x]][i]) {for (int &y : e[a[x]])if (!v[y][i]) v[y][i] = a[x];dfs(x + 1);for (int &y : e[a[x]])if (v[y][i] == a[x]) v[y][i] = 0;}}}void solve() {int n, m;cin >> n >> m;for (int i = 0, u, v; i < m; ++i) {cin >> u >> v;e[u].push_back(v);e[v].push_back(u);}for (int i = 1; i <= n; ++i) {if (!vis[i]) {cur = 0;a.resize(0);dfs0(i);for (int &y : e[i])if (!v[y][1]) v[y][1] = i;dfs(1);ans = ans * cur * 3;}}cout << ans << "\n";}
E - Permutation 状压DP
借用一下 Acfboy 的思路

// Murabito-B 21/04/26#include <bits/stdc++.h>using namespace std;#define int long longconst int N = 20;struct node {int x, y, z;bool operator<(node b) const { return x < b.x; }} a[N];int n, m, L[N], R[N], g[N], f[(1 << 19) + 5];bool flag[(1 << 19) + 5];int popcount(int x) { return x == 0 ? 0 : popcount(x & (x - 1)) + 1; }void solve() {cin >> n >> m;for (int i = 1; i <= m; ++i) cin >> a[i].x >> a[i].y >> a[i].z;sort(a + 1, a + 1 + m);for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {if (a[j].x == i) {L[i] = j;break;}}for (int j = m; j > 0; --j) {if (a[j].x == i) {R[i] = j;break;}}}for (int S = 1; S < (1 << n); ++S) {flag[S] = true;int k = popcount(S);if (L[k] == 0) continue;for (int i = 1; i <= n; ++i) g[i] = 0;for (int i = 1, j = 1; i <= k; ++i) {while ((S & (1 << j)) == 0) j++;for (int l = j; l <= n; ++l) g[l]++;j++;}for (int i = L[k]; i <= R[k]; ++i)flag[S] &= (g[a[i].y] <= a[i].z);}f[0] = 1;for (int S = 0; S < (1 << n); ++S)for (int i = 0; i <= 18; ++i)if (((S & (1 << i)) == 0) && flag[S | (1 << i)]) f[S | (1 << i)] += f[S];cout << f[(1 << n) - 1];}signed main() {ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);solve();}
