22.11.17
A
题意:
问你有多少个长度为
题解:
状压
复杂度分析:
时间复杂度:
空间复杂度:
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, p, q, r, dp[55][1001001], maxv, sum, pw = 1;
const int mod = 998244353;
signed main() {
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
scanf("%lld%lld%lld%lld%lld", &n, &m, &p, &q, &r);
maxv = max(p, max(q, r));
dp[0][0] = 1;
for (int i = 1; i <= n; i++) pw = pw * m % mod;
for (int i = 1; i <= n; i++)
for (int j = 0; j < (1ll << (p + q + r)); j++)
if (dp[i - 1][j]) {
if (m > maxv)
(dp[i][0] += dp[i - 1][j] * (m - maxv) % mod) %= mod;
for (int k = 1; k <= min(maxv, m); k++) {
int num = (j << k) & ((1ll << (p + q + r)) - 1) | (1ll << (k - 1));
if (((num >> (r - 1)) & 1) && ((num >> (q + r - 1)) & 1) &&
((num >> (p + q + r - 1)) & 1))
continue;
(dp[i][num] += dp[i - 1][j]) %= mod;
}
}
for (int j = 0; j < (1ll << (p + q + r)); j++) (sum += dp[n][j]) %= mod;
cout << (pw - sum + mod) % mod << endl;
return 0;
}
B
题意:
求出
题解:
我们先把
复杂度分析:
时间复杂度:
空间复杂度:
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n[1001001], b[1001001], mod, c[1001001], t[1001001];
char B[1001001];
void mi(int *a, int *b) {
for (int i = 0; i <= 1e6 + 10; i++) c[i] = 0;
c[0] = max(a[0], b[0]);
for (int i = 1; i <= a[0]; i++) {
c[i] += (a[i] - b[i]);
if (c[i] < 0) {
c[i + 1]--;
c[i] += 10;
}
}
while (c[c[0]] == 0 && c[0] > 1) c[0]--;
}
int mo(int *a, int b) {
int tmp = 0;
for (int i = a[0]; i; i--) tmp = (tmp * 10 % b + a[i]) % b;
return tmp;
}
int div(int *a, int b) {
int tmp = 0, ans = 0;
for (int i = a[0]; i; i--) {
tmp = tmp * 10 + a[i];
ans = ans * 10 + tmp / b;
tmp %= b;
}
return ans;
}
int get(int x) {
int ans = x;
for (int i = 2; i * i <= x; i++)
if (x % i == 0) {
ans -= ans / i;
while (x % i == 0) x /= i;
}
if (x > 1)
ans -= ans / x;
return ans;
}
int pow_mod(int a, int b) {
int ans = 1;
while (b) {
if (b & 1)
ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
signed main() {
freopen("b.in", "r", stdin);
freopen("b.out", "w", stdout);
char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') {
B[n[0]++] = ch;
ch = getchar();
}
for (int i = 1; i <= n[0]; i++) n[i] = (B[n[0] - i] - '0');
ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') {
B[b[0]++] = ch;
ch = getchar();
}
for (int i = 1; i <= b[0]; i++) b[i] = (B[b[0] - i] - '0');
cin >> mod;
t[0] = 1;
t[1] = 1;
mi(b, t);
int t1 = mo(c, mod);
int t2 = mo(b, mod);
mi(n, t);
int t3 = mo(c, get(mod));
if (div(c, get(mod)) > 0)
t3 += get(mod);
cout << t1 * pow_mod(t2, t3) % mod;
return 0;
}
C
题意:
给你个带权无向图,你可以任意交换两条边的边权,问你进行任意次操作之后,从
题解:
这题可以变化为从
复杂度分析:
时间复杂度:
空间复杂度:
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, u, v, x, y, z, e[1001001], dis[3][1001001], s[1001001];
queue<int> q;
vector<int> g[1001001];
void bfs(int id, int u) {
q.push(u);
dis[id][u] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : g[u])
if (dis[id][v] == -1) {
dis[id][v] = dis[id][u] + 1;
q.push(v);
}
}
}
signed main() {
freopen("c.in", "r", stdin);
freopen("c.out", "w", stdout);
scanf("%lld%lld%lld%lld%lld", &n, &m, &x, &y, &z);
for (int i = 1; i <= m; i++) {
scanf("%lld%lld%lld", &u, &v, &e[i]);
g[u].push_back(v);
g[v].push_back(u);
}
memset(dis, -1, sizeof(dis));
bfs(0, x);
bfs(1, y);
bfs(2, z);
sort(e + 1, e + m + 1);
for (int i = 1; i <= m; i++) s[i] = s[i - 1] + e[i];
int ans = 1ll << 50;
for (int i = 1; i <= n; i++)
if (dis[0][i] != -1 && dis[1][i] != -1 && dis[2][i] != -1 && dis[0][i] + dis[1][i] + dis[2][i] <= m)
ans = min(ans, s[dis[0][i] + dis[1][i] + dis[2][i]] + s[dis[1][i]]);
cout << ans;
return 0;
}
D
题意:
给你
题解:
小学的时候就学过一笔画问题,这题很类似。我们还是从简单的问题开始考虑,
复杂度分析:
时间复杂度:
空间复杂度:
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, w, tot, hs[100100], fa[100100], c[100100][5], mc;
struct node {
int xa, ya, xb, yb;
} s[100100], rs[100100];
vector<pair<int, int>> sx[100100], sy[100100];
int fd(int x) { return x == fa[x] ? x : fa[x] = fd(fa[x]); }
void mer(int x, int y) {
x = fd(x), y = fd(y);
if (x != y) {
mc++;
fa[x] = y;
for (int i = 1; i <= 4; i++) c[y][i] += c[x][i];
}
}
signed main() {
freopen("d.in", "r", stdin);
freopen("d.out", "w", stdout);
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld%lld%lld%lld", &s[i].xa, &s[i].ya, &s[i].xb, &s[i].yb);
if (s[i].xa > s[i].xb)
swap(s[i].xa, s[i].xb);
if (s[i].ya > s[i].yb)
swap(s[i].ya, s[i].yb);
hs[++w] = s[i].xa;
hs[++w] = s[i].ya;
hs[++w] = s[i].xb;
hs[++w] = s[i].yb;
}
sort(hs + 1, hs + w + 1);
w = unique(hs + 1, hs + w + 1) - hs - 1;
for (int i = 1; i <= n; i++) {
s[i].xa = lower_bound(hs + 1, hs + w + 1, s[i].xa) - hs;
s[i].xb = lower_bound(hs + 1, hs + w + 1, s[i].xb) - hs;
s[i].ya = lower_bound(hs + 1, hs + w + 1, s[i].ya) - hs;
s[i].yb = lower_bound(hs + 1, hs + w + 1, s[i].yb) - hs;
if (s[i].xa == s[i].xb)
sy[s[i].xa].push_back({ s[i].ya, s[i].yb });
else
sx[s[i].ya].push_back({ s[i].xa, s[i].xb });
}
for (int i = 1; i <= w; i++)
if (!sx[i].empty()) {
sort(sx[i].begin(), sx[i].end());
int lm = 0, rm = 0;
for (pair<int, int> x : sx[i]) {
if (x.first > rm) {
if (lm)
rs[++tot] = node{ lm, i, rm, i };
lm = x.first;
rm = x.second;
} else
rm = max(rm, x.second);
}
if (lm)
rs[++tot] = node{ lm, i, rm, i };
}
for (int i = 1; i <= w; i++)
if (!sy[i].empty()) {
sort(sy[i].begin(), sy[i].end());
int lm = 0, rm = 0;
for (pair<int, int> x : sy[i]) {
if (x.first > rm) {
if (lm)
rs[++tot] = node{ i, lm, i, rm };
lm = x.first;
rm = x.second;
} else
rm = max(rm, x.second);
}
if (lm)
rs[++tot] = node{ i, lm, i, rm };
}
for (int i = 1; i <= tot; i++) {
fa[i] = i;
c[i][1] = 2;
}
for (int i = 1; i <= tot; i++)
if (rs[i].ya == rs[i].yb) {
for (int j = 1; j <= tot; j++)
if (rs[j].xa == rs[j].xb) {
int fy = fd(j);
if ((rs[i].xa == rs[j].xa || rs[i].xb == rs[j].xa) &&
(rs[i].ya == rs[j].ya || rs[i].ya == rs[j].yb)) {
mer(i, j);
c[fy][1] -= 2;
c[fy][2]++;
} else if (((rs[i].xa == rs[j].xa || rs[i].xb == rs[j].xa) && rs[i].ya >= rs[j].ya &&
rs[i].ya <= rs[j].yb) ||
((rs[j].ya == rs[i].ya || rs[j].yb == rs[i].ya) && rs[j].xa >= rs[i].xa &&
rs[j].xa <= rs[i].xb)) {
mer(i, j);
c[fy][1]--;
c[fy][3]++;
} else if (rs[j].xa >= rs[i].xa && rs[j].xa <= rs[i].xb && rs[i].ya >= rs[j].ya &&
rs[i].ya <= rs[j].yb) {
mer(i, j);
c[fy][4]++;
}
}
}
int ans = 0, cc = 0;
for (int i = 1; i <= tot; i++)
if (fa[i] == i)
ans += max(1ll, m * (c[i][1] + c[i][2] * 2 + c[i][3] * 3 + c[i][4] * 4) / 2 - m / 2 * c[i][1] -
m * c[i][2] - m * 3 / 2 * c[i][3] - m * 2 * c[i][4]);
cout << ans - 1;
return 0;
}