School training 2019-09-22

to sum up

I do not have any feelings.

The only difficulty is the idea of ​​this USACO Platinum's probably not even NOIP to it.

This fully reflects the addition of a low level of I-tuned code, a NOIP not difficult to simulate game actually have a question not had time to see.

redistricting

Topic Portal

http://192.168.21.187/contest/30/problem/1

http://47.100.137.146/contest/30/problem/1

answer

The \ (H \) as \ (1 \) , \ (G \) seen \ (- 1 \) . So if a piece and \ (> 0 \) you do not need to pay a price, and if a piece of \ (<0 \) is required to pay \ (1 \) price.

Order \ (dp [I] \) is a front \ (I \) th minimal damage to cattle, \ (S_I \) represents the original prefix string and, obviously can be a formula dp.
\ [Dp [i] = \
min_ {j = i-k + 1} ^ {i-1} dp [j] + [s_j \ geq s_i] \] similar bzoj3831 [Poi2014] Little Bird practice, we only It requires \ (dp [j], s_j \) this tuple to establish it monotonously queue.

Because the test when I wrote half of the segment tree can do so only to think of it, so we simply direct the tree line finished. Accordingly, the following is the segment tree \ (O (n \ log n ) \) code segment tree for each node maintains a monotonically queue.

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

#define lc o << 1
#define rc o << 1 | 1

const int N = 3e5 + 7;
const int INF = 0x3f3f3f3f;

int n, m, T;
int s[N], dp[N];
char a[N];

struct Node {
    std::vector<int> q;
    int hd, tl;
} t[N << 3];

inline void build(int o, int L, int R) {
    t[o].hd = 1, t[o].tl = 0, t[o].q.pb(0);
    if (L == R) return;
    int M = (L + R) >> 1;
    build(lc, L, M), build(rc, M + 1, R);
}
inline void ins(int o, int L, int R, int x, int k) {
    while (t[o].hd <= t[o].tl && dp[k] <= dp[t[o].q[t[o].tl]]) --t[o].tl, t[o].q.pop_back();
    t[o].q.push_back(k), ++t[o].tl;
    if (L == R) return;
    int M = (L + R) >> 1;
    if (x <= M) ins(lc, L, M, x, k);
    else ins(rc, M + 1, R, x, k);
}
inline int qmin(int o, int L, int R, int l, int r, int k) {
    if (l > r) return INF;
    if (l <= L && R <= r) {
        while (t[o].hd <= t[o].tl && t[o].q[t[o].hd] < k - m) ++t[o].hd;
        if (t[o].hd > t[o].tl) return INF;
        else return dp[t[o].q[t[o].hd]];
    }
    int M = (L + R) >> 1;
    if (r <= M) return qmin(lc, L, M, l, r, k);
    if (l > M) return qmin(rc, M + 1, R, l, r, k);
    return std::min(qmin(lc, L, M, l, r, k), qmin(rc, M + 1, R, l, r, k));
}

inline void work() {
    build(1, 0, n << 1);
    ins(1, 0, n << 1, n, 0);
    for (int i = 1; i <= n; ++i) {
        dp[i] = std::min(qmin(1, 0, n << 1, 0, n + s[i] - 1, i), qmin(1, 0, n << 1, n + s[i], n << 1, i) + 1);
        ins(1, 0, n << 1, n + s[i], i);
    }
    printf("%d\n", dp[n]);
}

inline void init() {
    scanf("%d%d%s", &n, &m, a + 1);
    for (int i = 1; i <= n; ++i) s[i] = s[i - 1] + (a[i] == 'H' ? 1 : -1);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#else
    File(redistricting);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

exercise

Topic Portal

http://192.168.21.187/contest/30/problem/2

http://47.100.137.146/contest/30/problem/2

answer

It is easy to find, if we take the unconventional route each seen as a path cover, then meet the requirements of the subject line must be two paths covered Jiaotong than or equal to a side of the case.

Consider how to find such a solution.

For a point, we can find \ (f1 [x] \) is how many paths are included in the \ (x \) sub-tree, \ (F2 [the X-] \) is the presence of a number of endpoints path in \ (x \) sub-tree. So \ (ss [x] = f2 [x] - f1 [x] \) can indicate how much of the path of an endpoint in \ (x \) sub-tree, through (x \) \ back to \ (x \) sub-tree outside. \ (gg [x] \) indicates how many path from \ (x \) out of the sub-tree, through (x \) \ back to \ (fa [x] \) themselves or \ (fa [x] \) another sub-tree.

Back to the original question, for \ (u \ to lca \ to v \) such a path, and it has a number of paths overlap an edge. Consider first count all possible, then remove illegal. All possible, should be all in the presence of an endpoint \ (LCA \) path subtree, i.e. \ (F2 [LCA] \) .

Removed, there should be \ (u \ to lca \ to v \) of each point on the \ (X \) , to \ (fa [x] \) of \ (LCA \) and the absence of an endpoint \ ( X \) path, this can be \ (f1 [fa] -f1 [ x] -gg [x] \) FIG. But for \ (x \ to lca \) on the path closest to the \ (lca \) point \ (xx \) and with similar definitions of the point \ (YY \) , is rather special, is to be removed \ (fa [xx] \) of \ (LCA \) and in the absence of a terminal \ (XX \) and not in the \ (YY \) path, then there from \ (LCA \) out of the sub-tree and the starting point is not \ (XX \) or \ (YY \) path subtree, these two can be used\ (f1 [p] - f1 [xx] - f1 [yy] - gg [xx] - gg [yy] + mp [xx, yy] + (ss [p] - ss [xx] - ss [yy] + gg [xx] + gg [yy ]) \) is represented. Wherein \ (mp (x, y) \) represents the \ (X \) subtree out, to \ (fa [x] \) then went \ (Y \) the number of paths in the subtree.

Finally, the number of paths calculated should include your own, you need to \ (--1 \) . After the summation, because each of the two paths to be calculated, is divided by \ (2 \) .

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 2e5 + 7;

int n, m, dfc;
int siz[N], f[N], dep[N], son[N], dfn[N], pre[N], top[N];
int f1[N], f2[N], ss[N], dis[N], gg[N];
std::map<pii, int> mp;

struct Edge { int to, ne; } g[N << 1]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); }

struct Trail { int x, y, p, xx, yy; } a[N];

inline void dfs1(int x, int fa = 0) {
    dep[x] = dep[fa] + 1, f[x] = fa, siz[x] = 1;
    for fec(i, x, y) if (y != fa) dfs1(y, x), siz[x] += siz[y], siz[y] >= siz[son[x]] && (son[x] = y);
}
inline void dfs2(int x, int pa) {
    top[x] = pa, dfn[x] = ++dfc, pre[dfc] = x;
    if (!son[x]) return; dfs2(son[x], pa);
    for fec(i, x, y) if (y != son[x] && y != f[x]) dfs2(y, y);
}
inline int lca(int x, int y) {
    while (top[x] != top[y]) dep[top[x]] > dep[top[y]] ? x = f[top[x]] : y = f[top[y]];
    return dep[x] < dep[y] ? x : y;
}
inline int gson(int x, int p) {
    int d = 0;
    while (top[x] != top[p]) d = top[x], x = f[d];
    return x != p ? son[p] : d;
}

inline void dfs3(int x, int fa = 0) {
    for fec(i, x, y) if (y != fa)
        dfs3(y, x), f1[x] += f1[y], f2[x] += f2[y];
    ss[x] = f2[x] - f1[x];
}
inline void dfs4(int x, int fa = 0) {
    if (fa) dis[x] = dis[fa] + f1[fa] - f1[x] - gg[x];
    for fec(i, x, y) if (y != fa) dfs4(y, x);
}

inline void work() {
    dfs1(1), dfs2(1, 1);
    for (int i = 1; i <= m; ++i) {
        const int &x = a[i].x, &y = a[i].y;
        int &p = a[i].p = lca(x, y), &xx = a[i].xx = gson(x, p), &yy = a[i].yy = gson(y, p);
        ++mp[pii(xx, yy)], ++mp[pii(yy, xx)];
        ++f1[p], ++f2[x], ++f2[y], --f2[p], ++gg[xx], ++gg[yy];
    }
    dfs3(1), dfs4(1);
    ll ans = 0;
    for (int i = 1; i <= m; ++i) {
        const int &x = a[i].x, &y = a[i].y, &p = a[i].p;
        int cnt = f2[p], xx = a[i].xx, yy = a[i].yy;
        if (xx) {
            cnt -= dis[x] - dis[xx];
            cnt -= f1[x];
        }
        if (yy) {
            cnt -= dis[y] - dis[yy];
            cnt -= f1[y];
        }
        if (xx && yy) cnt -= f1[p] - f1[xx] - f1[yy] - gg[xx] - gg[yy] + mp[pii(xx, yy)] + (ss[p] - ss[xx] - ss[yy] + gg[xx] + gg[yy]);
        else if (xx) cnt -= f1[p] - f1[xx] - gg[xx] + (ss[p] - ss[xx] + gg[xx]);
        else if (yy) cnt -= f1[p] - f1[yy] - gg[yy] + (ss[p] - ss[yy] + gg[yy]);
        ans += cnt - 1;
    }
    printf("%lld\n", ans / 2);
}

inline void init() {
    read(n), read(m), m -= n - 1;
    int x, y;
    for (int i = 1; i < n; ++i) read(x), read(y), adde(x, y);
    for (int i = 1; i <= m; ++i) read(a[i].x), read(a[i].y);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#else
    File(exercise);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

tracking2

Topic Portal

http://192.168.21.187/contest/30/problem/3

http://47.100.137.146/contest/30/problem/3

answer

Obviously, for two adjacent \ (c_1, c_2 \) , and \ (c_1 \ neq c_2 \) , if \ (c_1 <c_2 \) , so \ (A_1 = c_1 \) ; otherwise \ (a_2 = c_2 \) .

We can put a lot of original \ (A \) sequence number that has been fixed number of intervals is divided into many sections, each section of the form is required any \ (K \) minimum number of adjacent \ (the y-\) , then there is every \ (x = 10 ^ 9 - y + 1 \) kinds of values.

This requirement is considered complete with dp. So \ (dp [i] \) for the first \ (i \) answers positions.

The first transfer is a \ (DP [I] DP = [I -. 1] \ CDOT X \) .

However, there is a possible problem \ (i-k + 1 .. i \) this period may be greater than all \ (X \) , do not satisfy the \ (\ min = x \) a.

So we need to lose part does not meet the meaning of the title, \ (i-k + 1 .. i \) This paragraph may all be greater than \ (the X-\) , where the program is \ ((x-1) ^ k \ ) . Then, since the \ (dp [i - 1] \) is legal, so it must be a \ (X \) followed by the \ (k-1 \) th larger than \ (X \) case number. Therefore, by subtracting the portion is multiplied by \ (dp [ik-1] \ cdot (x-1) ^ k \) a.

So the solution is to paragraph \ (DP [n-] \) , \ (n-\) length of this period.

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 1e5 + 7;
const int P = 1e9 + 7;

int n, k, m;
int c[N], dp[N];

inline int smod(int x) { return x >= P ? x - P : x; }
inline void sadd(int &x, const int &y) { x += y; x >= P ? x -= P : x; }
inline int fpow(int x, int y) {
    int ans = 1;
    for (; y; y >>= 1, x = (ll)x * x % P) if (y & 1) ans = (ll)ans * x % P;
    return ans;
}

inline int DP(const int &n, const int &x) {
    if (n <= 0) return 1;
    dp[0] = 1;
    int thx = fpow(x - 1, k);
    for (int i = 1; i <= n; ++i) {
        dp[i] = (ll)dp[i - 1] * x % P;
        if (i >= k + 1) sadd(dp[i], P - (ll)dp[i - k - 1] * thx % P);
        else if (i >= k) sadd(dp[i], P - thx);
    }
    return dp[n];
}

inline void work() {
    int ans = 1;
    for (int i = 1; i <= m; ++i) {
        int l = i, r = i, st;
        while (r < n && c[r + 1] == c[l]) ++r;
        st = r - l + k;
        if (r < m && c[r + 1] > c[r]) st -= k;
        if (l > 1 && c[l - 1] > c[l]) st -= k;
        ans = (ll)ans * DP(st, 1e9 - c[l] + 1) % P;
        i = r;
    }
    printf("%d\n", ans);
}

inline void init() {
    read(n), read(k), m = n - k + 1;
    for (int i = 1; i <= m; ++i) read(c[i]);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#else
    File(tracking2);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/contest20190922.html