8.1 test problem-solving report

\(\text{T1:}\)

Questions surface: poke here

\(Solution:\)

Start and twice \ (the DP \) , pretreatment two things:

  • \ (f1 [i] \) represented by section \ (I \) a maximum sub-segment and two end elements (push positive sequence)
  • \ (f2 [i] \) represented by section \ (I \) a maximum sub-segment and a beginning of the element (push reverse order)

Then consider enumerate a subscript \ (i \) , used to determine the absolute election less than that \ (k \) elements.
Then we need to know in the left of the current enumeration of the region \ (\ max (f1 [i ]) \) and the right of the \ (\ max (F2 [i]) \) .
This can start two \ (\ text {ST} \ ) table to achieveI actually tune for half an hour.
\ (AC \) Code:

/*--------------------------------
  Code name: REIGN.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <cmath>
#include <cstdio>
#include <cstring>
#define rg register
#define int long long 
const int MAXN = 100010;
inline int max(int a, int b) { return a > b ? a : b; }
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
int n, k, a[MAXN];
int fp[MAXN], fn[MAXN];
int stp[MAXN][22], stn[MAXN][22];
inline int askp(int l, int r) {
    int x = log(r - l + 1) / log(2);
    return max(stp[l][x], stp[r - (1 << x) + 1][x]);
}
inline int askn(int l, int r) {
    int x = log(r - l + 1) / log(2);
    return max(stn[l][x], stn[r - (1 << x) + 1][x]);
}
signed main() {
    for (rg int T = read(); T; --T) {
        n = read(), k = read();
        for (rg int i = 1; i <= n; ++i) a[i] = read();
        memset(stp, 0xaf, sizeof stp);
        memset(stn, 0xaf, sizeof stn);
        for (rg int i = 1; i <= n; ++i) stp[i][0] = max(stp[i - 1][0] + a[i], a[i]);
        for (rg int i = n; i >= 1; --i) stn[i][0] = max(stn[i + 1][0] + a[i], a[i]);
        for (rg int j = 1; j <= 20; ++j)
            for (rg int i = 1; i <= n - (1 << j) + 1; ++i) {
                stp[i][j] = max(stp[i][j - 1], stp[i + (1 << (j - 1))][j - 1]);
                stn[i][j] = max(stn[i][j - 1], stn[i + (1 << (j - 1))][j - 1]);
            }
        int ans = -1e18;
        for (rg int i = 2; i + k <= n; ++i) {
            int xp = askp(1, i - 1);
            int xn = askn(i + k, n);
            ans = max(ans, xp + xn);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

\(\text{T2:}\)

Questions surface: poke here

\(Solution:\)

First of all we need to do backwards, or very bad maintenance.
We then deleted from the back side, every time those points that may affect the answer to lost \ (\ text {BFS} \) .
Erase can then \ (\ text {set} \ ) implementation.
In fact, just fine to write, but how much time did the exam. . . \ (QwQ \)
\ (AC \) Code:

/*--------------------------------
  Code name: TRIPS.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <set>
#include <queue>
#include <cstdio>
#define rg register
using namespace std;
const int MAXN = 200010;
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
int n, m, k, now;
int ans[MAXN], dgr[MAXN], del[MAXN];
set < int > G[MAXN];
pair < int, int > edge[MAXN];
inline void bfs(int s) {
    if (dgr[s] >= k || del[s]) return;
    queue < int > q;
    --now, del[s] = 1, q.push(s);
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (auto v : G[u]) {
            --dgr[v];
            if (dgr[v] < k && !del[v])
                q.push(v), del[v] = 1, --now;
        }
    }
}
int main() {
    n = read(), m = read(), k = read();
    for (rg int u, v, i = 1; i <= m; ++i) {
        u = read(), v = read();
        ++dgr[u], ++dgr[v];
        edge[i] = make_pair(u, v);
        G[u].insert(v), G[v].insert(u);
    }
    now = n;
    for (rg int i = 1; i <= n; ++i) bfs(i);
    ans[m] = now;
    for (rg int i = m; i >= 1; --i) {
        int u = edge[i].first, v = edge[i].second;
        if (!del[u]) --dgr[v];
        if (!del[v]) --dgr[u];
        G[u].erase(v), G[v].erase(u);
        bfs(u), bfs(v), ans[i - 1] = now;
    }
    for (rg int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
    return 0;
}

\(\text{T3}\)

Questions surface: poke here

\(Solution\)

FIG consider building, a building between two adjacent lattices directed edges, directly over \ (\ text {Floyd} \ ) is determined to connectivity.
\ (AC \) Code:

/*--------------------------------
  Code name: SCC.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <cstdio>
#include <cstring>
#define rg register
const int MAXN = 410;
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
char rr[25], cc[25];
int r, c, pos[30][30], f[MAXN][MAXN];
int main() {
    r = read(), c = read();
    for (rg int i = 1; i <= r; ++i)
        for (rg int j = 1; j <= c; ++j)
            pos[i][j] = (i - 1) * c + j;
    char rr[30]; scanf("%s", rr + 1);
    char cc[30]; scanf("%s", cc + 1);
    for (rg int i = 1; i <= r; ++i) {
        if (rr[i] == '>')
            for (rg int j = 1; j < c; ++j) f[pos[i][j]][pos[i][j + 1]] = 1;
        else
            for (rg int j = 1; j < c; ++j) f[pos[i][j + 1]][pos[i][j]] = 1;
    }
    for (rg int j = 1; j <= c; ++j) {
        if (cc[j] == 'v')
            for (rg int i = 1; i < r; ++i) f[pos[i][j]][pos[i + 1][j]] = 1;
        else
            for (rg int i = 1; i < r; ++i) f[pos[i + 1][j]][pos[i][j]] = 1;
    }
    for (rg int k = 1; k <= pos[r][c]; ++k)
        for (rg int i = 1; i <= pos[r][c]; ++i)
            for (rg int j = 1; j <= pos[r][c]; ++j)
                if (i != j && j != k && i != k)
                    f[i][j] = f[i][j] | (f[i][k] & f[k][j]);
    for (rg int i = 1; i <= pos[r][c]; ++i)
        for (rg int j = 1; j <= pos[r][c]; ++j)
            if (i != j && !f[i][j]) return puts("NO"), 0;
    puts("YES");
    return 0;
}

\(\text{T4:}\)

Questions surface: poke here

\(Solution:\)

In fact, this is a big math problem
Geometric probability model.
First, we must define Condition for: the length \ (K \) divided into a segment \ (n-\) segment, such that \ (n-\) segments can form a closed polygon.
Here we must first be a small conclusion: circumference \ (K \) a \ (\ n-) polygons, one side is less than the maximum \ (k / 2 \)

Little proof:
If there is an edge to its length greater than or equal \ (k / 2 \) , then the other side of all this than the sum of the lengths a little edge, is clearly unreasonable.

Then, if we want a line to be divided into \ (n \) segment, which is to take on the segment \ (n-1 \) points.
Then we found positive with things to do, considering complement thought.
According to our previous conclusion small, irregular situation, if and only if there exists a line segment is greater than or equal modulus \ (k / 2 \)
That is, we have taken on the line segment which \ (n-1 \) th point you must fall within the same half of the segment.
This probability can be directly calculated: \ (P = C_n ^. 1/2 ^ {n--. 1} \)
(molecular determining an illegal longer than \ (k / 2 \) side, the denominator is the \ (n-1 \) th point to (1/2 \) \ probability falls with a probability of one half side of the segment)
followed by \ (1 \) subtracting like: \ (Ans-n-1 = / 2 ^ {n- } -1 \)
\ (the AC \) Code:

/*--------------------------------
  Code name: EQUILIBER.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <cstdio>
#define rg register
#define int long long 
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
const int p = 1e9 + 7;
inline int power(int x, int k) {
    int res = 1;
    for (; k; k >>= 1, x = 1ll * x * x % p)
        if (k & 1) res = 1ll * res * x % p;
    return res % p;
}
signed main() {
    int n = read(); read();
    printf("%lld\n", 1ll * (power(2, n - 1) - n + p) * power(2, (n - 1) * (p - 2)) % p);
    return 0;
}

\(\text{T5}\)

Questions surface: poke here

\(Solution:\)

First, we found that the original series, the position of each number does not matter.
So we just open a barrel just fine.
but! ! !
Input data have \ (10 ^ 9 \) ...
here is used to solve a greedy thought:
if a number is greater than the \ (the n-\ times2 \) , direct throw it away
. Why?
First, we delete a sequence number for the only two means, or to insert a number.
For greater than \ (n \ times2 \) number, to delete it than the cost of inserting at least a certain \ (n-\) the cost elements.
So read in, put the number of those lost.
Next consider \ (DP \) (like greed can do)
we recorded two values \ (mtong, maxx \) the biggest difference recorded \ (tong \) the maximum number of values and the number of columns.
Then each numerical enumeration \ (i \ in [1, maxx] \) is provided \ (f [j] \) represents the current time to enumerate
configured to length \ (J \) minimum steps required arrangement number.
Consider initialization and transfer :( directly write the code inside)
\ (AC \) Code:

/*--------------------------------
  Code name: PERMART.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <cstdio>
#include <algorithm>
#define rg register
#define int long long 
const int MAXN = 1000010;
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
int n, f[MAXN << 1], tong[MAXN << 1];
signed main() {
    for (rg int del, maxx, T = read(); T; --T) {
        n = read(), del = 0, maxx = 0;
        for (rg int x, i = 1; i <= n; ++i) {
            x = read();
            if (x > 2 * n) ++del;
            else ++tong[x], maxx = std ::max(maxx, x);
        }
        int mtong = 0;
        for (rg int i = 1; i <= maxx; ++i)
            mtong = std ::max(mtong, tong[i]);
        for (rg int i = 0; i <= mtong; ++i)
            f[i] = std ::abs(tong[1] - i);
        for (rg int i = 2; i <= maxx; ++i) {
            for (rg int j = mtong - 1; ~j; --j) f[j] = std ::min(f[j], f[j + 1]);
            for (rg int j = mtong; ~j; --j) f[j] += std ::abs(tong[i] - j);
        }
        int ans = 1e9;
        for (rg int i = 0; i <= mtong; ++i) ans = std ::min(ans, f[i]);
        printf("%lld\n", ans + del);
        for (rg int i = 0; i <= maxx; ++i) tong[i] = 0;
    }
    return 0;
}

\(\text{T6:}\)

Questions surface: poke here

\(Solution:\)

Or consider building map.
First two adjacent points even edges.
For an element value, an opening adjacent table, in order to reduce the number of edges can be built FIG daisySucker was to build the complete graphThe right side to handle it:

  • For the edge between two adjacent points, right 2
  • For chrysanthemums edges in the graph, right 1

After the finish shortest, the answer is divided by \ (2 \) to
\ (AC \) Code:

/*--------------------------------
  Code name: DIGJUMP.cpp
  Author: The Ace Bee
  This code is made by The Ace Bee
--------------------------------*/
#include <queue>
#include <cstdio>
#include <cstring>
#define rg register
#define int long long 
const int MAXN = 100100;
const int MAXM = 300010;
using namespace std;
inline int read() {
    int s = 0; bool f = false; char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
    return f ? -s : s;
}
int tot, head[MAXN], nxt[MAXM << 1], ver[MAXM << 1], w[MAXM << 1];
inline void Add_edge(int u, int v, int d)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, w[tot] = d; }
int tong[15], tt, hd[15], nt[MAXN], vr[MAXN];
inline void Add_relate(int u, int v)
{ nt[++tt] = hd[u], hd[u] = tt, vr[tt] = v; }
int n, exi[MAXN], dis[MAXN];
queue < int > q;
inline void spfa(int s) {
    memset(exi, 0, sizeof exi);
    memset(dis, 0x7f, sizeof dis);
    q.push(s), exi[s] = 1, dis[s] = 0;
    while (!q.empty()) {
        int u = q.front(); q.pop(), exi[u] = 0;
        for (rg int i = head[u]; i; i = nxt[i]) {
            int v = ver[i];
            if (dis[v] > dis[u] + w[i]) {
                dis[v] = dis[u] + w[i];
                if (!exi[v]) exi[v] = 1, q.push(v);
            }
        }
    }
}
signed main() {
    char s[MAXN];
    scanf("%s", s + 1), n = strlen(s + 1);
    for (rg int x, i = 1; i <= n; ++i) {
        x = s[i] ^ 48, ++tong[x], Add_relate(x, i);
        if (i != n) Add_edge(i, i + 1, 2), Add_edge(i + 1, i, 2);
    }
    for (rg int x = 0; x < 10; ++x)
        if (tong[x] > 1)
            for (rg int i = hd[x]; i; i = nt[i])
                Add_edge(n + x + 1, vr[i], 1), Add_edge(vr[i], n + x + 1, 1);
    spfa(1);
    printf("%lld\n", dis[n] >> 1);
    return 0;
}

End Sahua \ (qwq \)

Guess you like

Origin www.cnblogs.com/zsbzsb/p/11285059.html