School training 2019-10-03

The topic of today's exams are quite friendly.

Suitable NOIP difficulty, topics and data quality strength almost perfect, indeed JS captain xyx title.But why T3 of std on our university OJ T out of it

T1 as a sign question, more in line with the difficulty NOIP D2T1, there is a certain amount of thinking, but thinking is very small, whether it is to find the law or direct push can get positive solutions very quickly, and very easy to beat.

T2 has some problems face difficulty in understanding the text, but to solve word problems in the future, as long as a notice 每个单位 不会在同一种联系中出现大于一次of limitation, and observe the observation sample 2, after 3, can reach the right approach, the difficulty is slightly lower than NOIP D2T2 difficulty, similar to last year's D1T3 difficulty.

T3 is prone to some idea of ​​partial band, it is necessary to consider whether timely some restrictions necessary, whether narrow limits. If the thoughtful words, this question can also use a variety of data structures quickly know the result. About the difficulty similar to D2T2 or 2017 and prior D1T3.

In the simulated race NOIP, it is worth noting that a matter of time, after all NOIP only 3.5h, can not NOIP as 5h.


T1. End of Time review

Topic Portal

http://192.168.21.187/contest/31/problem/1 = http://192.168.21.187/problem/1310

http://47.100.137.146/contest/31/problem/1 = http://47.100.137.146/problem/1310

answer

Found the ultimate limit is \ (N \ Leq 64-\) , it is easy to think about this topic and binary.

It found that for a \ (T \) points have to complete graph, from \ (1 \) to \ (T \) of exactly the number of program \ (T-2 ^ {2} \) .

Contact the two conclusions above, we can easily think of the \ (Y \) binary split (split into a bunch of \ (2 \) integer powers and), and then to establish a complete graph, then we can from this FIG found corresponding to \ (N \) solution for \ (2 \) of the power o'clock. Let \ (1 \) to these points can be built side respectively.

#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;
}

ll Y;
int dy[100];
pii ans[10000 + 7];

inline void work() {
    int n;
    if (Y > 1) n = std::__lg(Y - 1) + 4;
    else n = 3;
    int ccc = 0, cnt = 0;
    for (int i = n - 1; i >= 2; --i) {
        for (int j = n; j > i; --j) ans[++cnt] = pii(i, j);
        dy[ccc++] = i;
    }
    for (int i = 0; Y; ++i, Y >>= 1) if (Y & 1) ans[++cnt] = pii(1, dy[i]);
    printf("%d %d\n", n,cnt);
    for (int i = 1; i <= cnt; ++i) printf("%d %d\n", ans[i].fi, ans[i].se);
}

inline void init() {
    read(Y);
}

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

T2. When refrain Dr.

Topic Portal

http://192.168.21.187/contest/31/problem/2 = http://192.168.21.187/problem/1311

http://47.100.137.146/contest/31/problem/2 = http://47.100.137.146/problem/1311

answer

Because each unit does not appear in more than one time in the same kind of contact, so in the future if we build out the entire map, will be divided into a lot of rings and chains.

We found that the direct damage can calculate the number of permutations of demand is not very good, so the program can not be converted into the number of destroyed. Not destroy it later means that the original two adjacent ring on a point of conversion, but also the neighboring (and edge color can not be changed) on the same ring. The same chain.

Inside a ring, we want to make every point, without departing from the ring. If the length of the loop is \ (len \) , if \ (len \) is odd, then, can obviously only do not move, contributions to the \ (1 \) ; if \ (len \) is even, then our replacement program has two kinds: the first is a folded along the vertical edges; a second rotation even length, the number of programs in both cases is \ (\ FRAC len {2} \) , then the contribution of this loop as \ (len \) .

UPD: Some of the above problems, there is a length of an odd number of rings.

But ultimately, for \ (X \) of length \ (I \) cycloalkyl, which may be done between each overall transposition. So \ (X \) of length \ (I \) contributed ring is \ (X! I ^ X \) .

The same chain.

Chain to chain length is divided into an even number and an odd number of points of the point.

An odd number of points of the chain is no method of operation, only to remain intact, contribute to the \ (1 \) ; it \ (X \) of length \ (I \) contribute to chain \ (X \!) .

Chain may be folded an even number of points along the vertical, so the contribution to the \ (2 \) ; it \ (X \) of length \ (I \) contribute to chain \ (x 2 ^ x \! ) .

The same chain length or the contribution of each pile loop ride up on it.

Finally, \ (n! \) Minus the answer above. Time complexity \ (O (n-) \) .

#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;
const int P = 1e9 + 7;

int n, m1, m2;
int to1[N], to2[N], vis[N];
int huan[N], lian1[N], lian2[N];
int fac[N], inv[N], ifac[N];

inline void build() {
    for (int i = 1; i <= n; ++i) if (!vis[i] && !to1[i]) {
        int x = i, cnt = 0;
        while (x) {
            ++cnt, vis[x] = 1;
            if (cnt & 1) x = to2[x];
            else x = to1[x];
        }
        ++lian1[cnt];
    }
    for (int i = 1; i <= n; ++i) if (!vis[i] && !to2[i]) {
        int x = i, cnt = 0;
        while (x) {
            ++cnt, vis[x] = 1;
            if (cnt & 1) x = to1[x];
            else x = to2[x];
        }
        ++lian2[cnt];
    }
    for (int i = 1; i <= n; ++i) if (!vis[i]) {
        int x = i, cnt = 0;
        while (!vis[x]) {
            ++cnt, vis[x] = 1;
            if (cnt & 1) x = to1[x];
            else x = to2[x];
        }
        ++huan[cnt];
    }
}

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 void ycl() {
    fac[0] = 1; for (int i = 1; i <= n; ++i) fac[i] = (ll)fac[i - 1] * i % P;
    inv[1] = 1; for (int i = 2; i <= n; ++i) inv[i] = (ll)(P - P / i) * inv[P % i] % P;
    ifac[0] = 1; for (int i = 1; i <= n; ++i) ifac[i] = (ll)ifac[i - 1] * inv[i] % P;
}

inline void work() {
    build();
    ycl();
    int ans = 1;
    for (int i = 1; i <= n; ++i) {
        if (!(i & 1)) ans = (ll)ans * fac[lian1[i]] % P * fpow(2, lian1[i]) % P;
        else ans = (ll)ans * fac[lian1[i]] % P;
        if (!(i & 1)) ans = (ll)ans * fac[lian2[i]] % P * fpow(2, lian2[i]) % P;
        else ans = (ll)ans * fac[lian2[i]] % P;
        if (!(i & 1)) ans = (ll)ans * fac[huan[i]] % P * fpow(i, huan[i]) % P;
//      if (i <= 10) dbg("i = %d, lian1 = %d, lian2 = %d, huan = %d\n", i, lian1[i], lian2[i], huan[i]);
    }
//  dbg("ans = %d\n", ans);
    ans = fac[n] + P - ans;
    printf("%d\n", ans % P);
}

inline void init() {
    read(n), read(n), read(m1), read(m2);
    int x, y;
    for (int i = 1; i <= m1; ++i) read(x), read(y), to1[x] = y, to1[y] = x;
    for (int i = 1; i <= m2; ++i) read(x), read(y), to2[x] = y, to2[y] = x;
}

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

T3. Had two rebirth

Topic Portal

http://192.168.21.187/contest/31/problem/3 = http://192.168.21.187/problem/1312

http://47.100.137.146/contest/31/problem/3 = http://47.100.137.146/problem/1312

answer

Exam when I wanted more, think we should maintain the edge is a point located on the shortest path map \ (x \) point can be reached, and the other end is not (x \) \ dominated side.

As described above, for such an edge, and the spread of a set of properties shortest "path a shortest path between two points is the most short-circuit", it is easy to get a later updated with this edge \ (X \ ) the length of the shortest path, i.e. \ (DIS [U] W + DIS + [V] - DIS [X] \) .

But then, we can find to do the most short-circuit diagram is no necessary. Only the shortest path tree can be. For the new path, there must be a non-tree edge, the \ (X \) external to the sub-sub-tree with the tree. So we only need to use it segment tree merge maintain the contribution of all to meet the conditions of the minimum non-tree edge on it.

Time complexity \ (O (n-\ log n-) \) .

#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<ll, 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;
const int M = 5e5 + 7;
const ll INF = 0x3f3f3f3f3f3f3f3f;

int n, m, dfc, nod;
int dfn[N], rt[N], siz[N];
bool vis[N];
ll dis[N], ans[N];
std::priority_queue<pii, std::vector<pii>, std::greater<pii>> q;

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

struct Node {
    int lc, rc;
    ll val;
} t[(M + N) * 20];

inline void qins(int &o, int L, int R, int x, ll k) {
    if (!o) o = ++nod, t[o].val = k;
    else smin(t[o].val, k);
    if (L == R) return;
    int M = (L + R) >> 1;
    if (x <= M) qins(t[o].lc, L, M, x, k);
    else qins(t[o].rc, M + 1, R, x, k);
}
inline ll qmin(int o, int L, int R, int l, int r) {
//  dbg("o = %d, L = %d, R = %d, l = %d, r = %d, t[o].val = %lld\n", o, L, R, l, r, t[o].val);
    if (!o) return INF;
    if (l > r) return INF;
    if (l <= L && R <= r) return t[o].val;
    int M = (L + R) >> 1;
    if (r <= M) return qmin(t[o].lc, L, M, l, r);
    if (l > M) return qmin(t[o].rc, M + 1, R, l, r);
    return std::min(qmin(t[o].lc, L, M, l, r), qmin(t[o].rc, M + 1, R, l, r));
}
inline int merge(int o, int p) {
    if (!o || !p) return o ^ p;
    t[o].val = std::min(t[o].val, t[p].val);
    t[o].lc = merge(t[o].lc, t[p].lc);
    t[o].rc = merge(t[o].rc, t[p].rc);
    return o;
}

inline void dijkstra() {
    memset(dis, 0x3f, sizeof(dis));
    dis[1] = 0, q.push(pii(dis[1], 1));
    while (!q.empty()) {
        int x = q.top().se; q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        for fec(i, x, y) if (smin(dis[y], dis[x] + g[i].w)) q.push(pii(dis[y], y));
    }
}

inline void dfs1(int x, int fa = 0) {
    dfn[x] = ++dfc, siz[x] = 1;
    for fec(i, x, y) if (y != fa && dis[y] == dis[x] + g[i].w) dfs1(y, x), siz[x] += siz[y];
}

inline void dfs2(int x, int fa = 0) {
    for fec(i, x, y) if ((y != fa || dis[x] != dis[y] + g[i].w) && dis[y] != dis[x] + g[i].w) qins(rt[x], 1, n, dfn[y], dis[y] + dis[x] + g[i].w);//, dbg("x = %d, y = %d, g[i].w = %d\n", x, y, g[i].w);
    for fec(i, x, y) if (y != fa && dis[y] == dis[x] + g[i].w) dfs2(y, x), rt[x] = merge(rt[x], rt[y]);
    if (fa) {
//      dbg("rt[%d] = %d, %lld, %lld\n", x, rt[x], qmin(rt[x], 1, n, 1, dfn[x] - 1), qmin(rt[x], 1, n, dfn[x] + siz[x], n));
        ans[x] = std::min(qmin(rt[x], 1, n, 1, dfn[x] - 1), qmin(rt[x], 1, n, dfn[x] + siz[x], n));
        if (ans[x] == INF) ans[x] = -1;
        else ans[x] -= dis[x];
    }
}

inline void work() {
    dijkstra();
//  for (int i = 1; i <= n; ++i) dbg("dis[%d] = %lld\n", i, dis[i]);
    dfs1(1);
    dfs2(1);
    for (int i = 1; i <= n; ++i) printf("%lld%c", ans[i], " \n"[i == n]);
}

inline void init() {
    read(n), read(n), read(m);
    int x, y, z;
    for (int i = 1; i <= m; ++i) read(x), read(y), read(z), adde(x, y, z);
}

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

Guess you like

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