NOIP提高組模擬賽24[matrix block graph]
阿新 • • 發佈:2022-05-10
T1. 大力狀壓。沒了
#include <cstdio> #include <cstring> #include <cctype> #include <iostream> #include <sstream> #include <stack> #include <cmath> #include <algorithm> #include <map> #include <deque> #include <bitset> #include <list> using namespace std; typedef long long ll; typedef unsigned long long ull; int read() { int x = 0; char c; bool f = 0; while (!isdigit(c = getchar())) { if (c == '-') { f = 1; } } do { x = (x << 1) + (x << 3) + (c ^ 48); } while (isdigit(c = getchar())); if (f) { return -x; } return x; } const int maxn = 12, maxk = 1030; int n, m, MAX; char str[maxn]; int p[maxn][maxn]; int a[maxn]; int f[maxn][maxk][maxk], g[maxn][maxk], las[maxn][maxk]; int main() { #ifndef DEBUG freopen("matrix.in", "r", stdin); freopen("matrix.out", "w", stdout); #endif n = read(), m = read(); for (int i = 1; i <= n; ++i) { scanf("%s", str); for (int j = 0; j < m; ++j) { a[i] |= ((str[j] - '0') << j); } } int MAX = 1 << m; for (int i = 1; i <= n; ++i) { for (int j = 0; j < m; ++j) { p[i][j] = read(); } for (int j = 0; j < MAX; ++j) { int tmp = 0; for (int k = 0; k < m; ++k) { if (j & (1 << k)) { tmp += p[i][k]; } } g[i][j] = tmp; } } memset(f, 0x3f, sizeof f); for (int i = 0; i < MAX; ++i) { for (int j = 0; j < MAX; ++j) { f[0][i][j] = 0; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < MAX; ++j) { for (int u = 0; u < MAX; ++u) { if ((j | u) != MAX - 1) { continue; } for (int k = 0; k < MAX; ++k) { if (f[i][j][k] == 0x3f3f3f3f) { continue; } int tmp = u | ((u << 1) & (MAX - 1)) | (u >> 1) | k | a[i + 1]; if (i == 0) { tmp = u | ((u << 1) & (MAX - 1)) | (u >> 1) | a[i + 1]; } f[i + 1][tmp][u] = min(f[i + 1][tmp][u], f[i][j][k] + g[i + 1][u]); } } } } int ans = 0x7fffffff; for (int i = 0; i < MAX; ++i) { ans = min(ans, f[n][MAX - 1][i]); } printf("%d\n", ans); }
T2. 第一問簡單題排個序就完了,第二問線段樹維護 (這兩問一點關係沒有……)
#include <cstdio> #include <cstring> #include <cctype> #include <iostream> #include <stack> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <deque> #include <bitset> #include <list> using namespace std; typedef long long ll; typedef unsigned long long ull; int read() { int x = 0; char c; bool f = 0; while (!isdigit(c = getchar())) { if (c == '-') { f = 1; } } do { x = (x << 1) + (x << 3) + (c ^ 48); } while (isdigit(c = getchar())); if (f) { return -x; } return x; } const int maxn = 5e5 + 10, mod = 1e9 + 7; int n; struct data { int key, val; } a[maxn]; bool cmp(const data &a, const data &b) { if (a.val == b.val) { return a.key < b.key; } return a.val > b.val; } bool cmp2(const data &a, const data &b) { if (a.val == b.val) { return a.key < b.key; } return a.val < b.val; } struct SegmentTree { #define ls (p << 1) #define rs ((p << 1) | 1) struct data { int val, key, now, from; int lazy, mn; } tr[maxn << 2]; int mim(int x, int y) { if (x == -1) { return y; } if (y == -1) { return x; } if (a[x].key != a[y].key) { return a[x].key < a[y].key ? x : y; } return a[x].val < a[y].val ? x : y; } void PushUp(int p) { if (tr[ls].now <= tr[rs].now) { tr[p].now = tr[ls].now; tr[p].from = tr[ls].from; } else { tr[p].now = tr[rs].now; tr[p].from = tr[rs].from; } tr[p].mn = mim(tr[ls].mn, tr[rs].mn); } void PushDown(int p) { if (!tr[p].lazy) { return; } tr[ls].lazy += tr[p].lazy; tr[rs].lazy += tr[p].lazy; tr[ls].now += tr[p].lazy; tr[rs].now += tr[p].lazy; tr[p].lazy = 0; } void Build(int p, int l, int r) { if (l == r) { tr[p].val = a[l].val; tr[p].now = tr[p].key = a[l].key; tr[p].from = l; tr[p].mn = l; return; } int mid = (l + r) >> 1; Build(ls, l, mid); Build(rs, mid + 1, r); PushUp(p); } void Modify(int p, int l, int r, int pos) { if (l == r) { tr[p].key = 0x3f3f3f3f; tr[p].now = 0x3f3f3f3f; tr[p].mn = -1; return; } PushDown(p); int mid = (l + r) >> 1; if (pos <= mid) { Modify(ls, l, mid, pos); } else { Modify(rs, mid + 1, r, pos); } PushUp(p); } void Modify(int p, int l, int r, int L, int R) { if (L > R) { return; } if (L <= l && r <= R) { --tr[p].lazy; --tr[p].now; return; } PushDown(p); int mid = (l + r) >> 1; if (L <= mid) { Modify(ls, l, mid, L, R); } if (R > mid) { Modify(rs, mid + 1, r, L, R); } PushUp(p); } int Query(int p, int l, int r, int L, int R) { if (L > R) { return -1; } if (L <= l && r <= R) { return tr[p].mn; } PushDown(p); int mid = (l + r) >> 1, ans = -1; if (L <= mid) { ans = mim(ans, Query(ls, l, mid, L, R)); } if (R > mid) { ans = mim(ans, Query(rs, mid + 1, r, L, R)); } PushUp(p); return ans; } } T; int pre[maxn], nxt[maxn]; int main() { #ifndef DEBUG freopen("block.in", "r", stdin); freopen("block.out", "w", stdout); #endif n = read(); for (int i = 1; i <= n; ++i) { a[i].key = read(); a[i].val = read(); } sort(a + 1, a + n + 1, cmp); ll ans = 1; int tot = 1; for (int i = 1; i <= n; ++i) { if (a[i].val == a[i - 1].val) { ans = ans * min(i, a[i].key + tot) % mod; ++tot; } else { ans = ans * min(i, a[i].key) % mod; tot = 1; } } printf("%lld\n", ans); sort(a + 1, a + n + 1, cmp2); for (int i = 1; i <= n; ++i) { if (a[i].val == a[i - 1].val) { pre[i] = pre[i - 1]; } else { pre[i] = i - 1; nxt[i - 1] = i; } } for (int i = n; i; --i) { if (!nxt[i]) { nxt[i] = nxt[i + 1]; } } nxt[n] = n; T.Build(1, 1, n); for (int i = 1; i <= n; ++i) { int tmp; if (T.tr[1].now == 1) { tmp = T.Query(1, 1, n, 1, nxt[T.tr[1].from]); } else { tmp = T.tr[1].mn; } printf("%d %d\n", a[tmp].key, a[tmp].val); T.Modify(1, 1, n, tmp); T.Modify(1, 1, n, 1, pre[tmp]); } }
T3. 隨機化即可(霧)
#include <cstdio> #include <cstring> #include <cctype> #include <iostream> #include <sstream> #include <stack> #include <cmath> #include <algorithm> #include <map> #include <deque> #include <queue> #include <bitset> #include <list> using namespace std; typedef long long ll; typedef unsigned long long ull; int read() { int x = 0; char c; bool f = 0; while (!isdigit(c = getchar())) { if (c == '-') { f = 1; } } do { x = (x << 1) + (x << 3) + (c ^ 48); } while (isdigit(c = getchar())); if (f) { return -x; } return x; } const int maxn = 1e3 + 10, maxe = 2e3 + 10; struct Graph { int head[maxn], len; int nxt[maxe << 1], to[maxe << 1], dis[maxe << 1]; void Ins(int u, int v, int d) { to[++len] = v; nxt[len] = head[u]; dis[len] = d; head[u] = len; } } G; int n, m, tot; ull dis1[maxn], disn[maxn]; bool vis[maxn]; struct data { ull dis; int u; data(ull a, int b) { dis = a; u = b; } bool operator < (const data &b) const { return dis > b.dis; } }; ull x; void Dijkstra(int s, ull *dis) { priority_queue<data> q; memset(vis, 0, sizeof vis); dis[s] = 0; q.push(data(0, s)); while (!q.empty()) { int u = q.top().u; q.pop(); if (vis[u]) { continue; } vis[u] = 1; for (int i = G.head[u]; i; i = G.nxt[i]) { int v = G.to[i]; if (G.dis[i] == -1) { if (dis[v] > dis[u] + x) { dis[v] = dis[u] + x; q.push(data(dis[v], v)); } } else { if (dis[v] > dis[u] + G.dis[i]) { dis[v] = dis[u] + G.dis[i]; q.push(data(dis[v], v)); } } } } } bool ok[maxn]; ull rand(ull l, ull r) { return 1ull * rand() * rand() % (r - l + 1) + l; } void Test() { memset(dis1, 0x3f, sizeof dis1); memset(disn, 0x3f, sizeof disn); Dijkstra(1, dis1); Dijkstra(n, disn); for (int i = 1; i <= n; ++i) { if (dis1[i] + disn[i] == dis1[n]) { ok[i] = 1; } } } int main() { srand(time(0)); #ifndef DEBUG freopen("graph.in", "r", stdin); freopen("graph.out", "w", stdout); #endif n = read(), m = read(); ull MAX = 0; for (int i = 1; i <= m; ++i) { int u = read(), v = read(), d = read(); if (d == -1) { ++tot; } if (d != -1) { MAX = max(MAX, 1ull * d); } G.Ins(u, v, d); G.Ins(v, u, d); } if (n < 1000) { for (x = 0; x <= 100000; x += 4) { Test(); } } else { x = 0; Test(); for (ull l = 1; l <= 1e6; l += 1e4) { for (int j = 1; j <= 5; ++j) { x = rand(l, l + 1e4 - 1); Test(); } } for (ull l = 1e6; l <= MAX; l += 1e7) { for (int j = 1; j <= 5; ++j) { x = rand(l, l + 1e7 - 1); Test(); } } x = 1e14; Test(); } for (int i = 1; i <= n; ++i) { if (ok[i]) { putchar('1'); } else { putchar('0'); } } putchar('\n'); }