宝藏 冲刺NOIP2021模拟17 寻找道路 冲刺NOIP2021模拟17 猪国杀 冲刺NOIP2021模拟17 数树

T1

首先对序列排序,中位数指针是单调的,现在要做的就是动态维护中位数左边的最小k个值和右边的最小k个

权值线段树单点修改区间查询即可

T2

不难发现暴力直接spfa

对于这种01序列,我们发现若不考虑前导0,每个数的大小与长度和字典序有关

于是我们可以将只靠0就可以到达的点缩成一点,然后bfs并强制使队列中的值满足递增(模拟dij)

于是我们可以取出所有大小相同的队头,对这些队头先转移0,再转移1

T3

对于每中序列肯定是县排序后取最小的

于是我们可以考虑枚举这个序列,并考虑向里面添加元素,也就是说假如这个序列合法长度为k,我们要恰好计算它k次

于是有一个式子

\[\sum_{i=0}^{n}\sum_{j=1}^{A}\sum_{k=1}^{n-i}g_{i,j-1,m-k* j}\sum_{t>=k}{n\choose i}{n-i\choose t}{(A-j)^{n-i-t}} \]

其中\(g_{i,j,k}\)表示长度为 i 且最大值不超过 j ,总和不超过 k 的序列个数

\[g_{i,j,k}=\sum_{t=0}^{i}(-1)^t{i\choose t}{k-t* j\choose i} \]

这个容斥是在枚举大于j的个数,也就是强制使 t 个大于 j ,然后做插板法

注意到这个插板法上下都少个1,因为这个数组定义是总和不超过k

T4

这个发现T2的数据范围很小,可以考虑状压

枚举T2的根,然后预处理出每个节点的儿子集合

\(f_{u,S}\)表示T1的 u 点的儿子集合和T2中的 S 集合双射的方案数,S 表示T2中某个点 v 的儿子集合

每次T1和T2匹配时枚举T1u的儿子和T2的某点匹配就行了

代码

这个是格式化后的代码

T1

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 11;
struct wp_ {
    int w, t;
} a[N];
struct tree {
    int l, r;
    int num;
    int sum;
} tre[2][4 * N];
int n, t, q;
int maxx;
int ans[N];
inline int read() {
    int s = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }
    return s;
}
inline int max_(int a, int b) { return a > b ? a : b; }
bool cmpw(wp_ a, wp_ b) { return a.w < b.w; }
void insert(int i, int p, int x, int w) {
    if (tre[p][i].l == tre[p][i].r) {
        tre[p][i].num += w;
        tre[p][i].sum += w * x;
        return;
    }
    int mid = (tre[p][i].l + tre[p][i].r) >> 1;
    if (x <= mid)
        insert(i << 1, p, x, w);
    else
        insert(i << 1 | 1, p, x, w);
    tre[p][i].sum += x * w;
    tre[p][i].num += w;
    return;
}
int query(int i, int p, int k) {
    if (tre[p][i].l == tre[p][i].r)
        return k * tre[p][i].l;
    if (tre[p][i << 1].num >= k)
        return query(i << 1, p, k);
    else
        return tre[p][i << 1].sum + query(i << 1 | 1, p, k - tre[p][i << 1].num);
}
bool check(int x, int num) {
    if (x - num / 2 <= 0 || x + num / 2 > n)
        return 0;
    return (query(1, 0, num / 2) + query(1, 1, num / 2) + a[x].t) <= t;
}
void solve() {
    int p = n;
    for (int i = 1; i < n; ++i) insert(1, 0, a[i].t, 1);
    for (int i = 1; i <= n; i += 2) {
        while (p > 0 && !check(p, i)) {
            --p;
            if (!p)
                break;
            insert(1, 0, a[p].t, -1);
            insert(1, 1, a[p + 1].t, 1);
        }
        if (p)
            ans[i] = a[p].w;
        else
            ans[i] = -1;
    }
    return;
}
void build(int i, int l, int r) {
    tre[0][i] = tre[1][i] = { l, r };
    if (l == r)
        return;
    int mid = (l + r) >> 1;
    build(i << 1, l, mid);
    build(i << 1 | 1, mid + 1, r);
    return;
}
signed main() {
    FILE* x = freopen("treasure.in", "r", stdin);
    x = freopen("treasure.out", "w", stdout);
    n = read();
    t = read();
    q = read();
    for (int i = 1; i <= n; ++i) {
        a[i].w = read();
        a[i].t = read();
        maxx = max_(maxx, a[i].t);
    }
    sort(a + 1, a + n + 1, cmpw);
    build(1, 1, maxx);
    solve();
    for (int x, i = 1; i <= q; ++i) printf("%lld\n", ans[read()]);
    return 0;
}

T2

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e6 + 11;
const int mod = 1e9 + 7;
struct qxxx {
    int v, next, w;
} cc[2 * N];
bool jud[N];
int n, m;
int d[N], k[N];
int x[N], y[N], z[N];
int ans[N];
int first[N], cnt;
vector<int> vct;
queue<int> que, dui;
inline int read() {
    int s = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }
    return s;
}
void qxx(int u, int v, int w) {
    cc[++cnt] = { v, first[u], w };
    first[u] = cnt;
    return;
}
void dij() {
    memset(d, 0x3f, sizeof(d));
    d[1] = 0;
    dui.push(1);
    int x;
    while (dui.size()) {
        x = dui.front();
        dui.pop();
        for (int i = first[x]; i; i = cc[i].next)
            if (d[cc[i].v] && cc[i].w == 0) {
                d[cc[i].v] = 0;
                dui.push(cc[i].v);
            }
    }
    return;
}
void bfs() {
    memset(d, 0x3f, sizeof(d));
    d[1] = 0;
    ans[1] = 0;
    que.push(1);
    int x;
    while (que.size()) {
        x = que.front();
        vct.clear();
        while (que.size() && ans[que.front()] == ans[x]) {
            vct.push_back(que.front());
            que.pop();
        }
        for (int j = 0; j < vct.size(); ++j) {
            x = vct[j];
            for (int i = first[x]; i; i = cc[i].next)
                if (d[cc[i].v] > mod && cc[i].w == 0) {
                    d[cc[i].v] = d[x] + 1;
                    ans[cc[i].v] = ans[x] * 2 % mod;
                    que.push(cc[i].v);
                }
        }
        for (int j = 0; j < vct.size(); ++j) {
            x = vct[j];
            for (int i = first[x]; i; i = cc[i].next)
                if (d[cc[i].v] > mod && cc[i].w == 1) {
                    d[cc[i].v] = d[x] + 1;
                    ans[cc[i].v] = (ans[x] * 2 + 1) % mod;
                    que.push(cc[i].v);
                }
        }
    }
    return;
}
signed main() {
    FILE* p = freopen("path.in", "r", stdin);
    p = freopen("path.out", "w", stdout);
    n = read();
    m = read();
    for (int i = 1; i <= m; ++i) {
        x[i] = read();
        y[i] = read();
        z[i] = read();
        qxx(x[i], y[i], z[i]);
    }
    dij();
    memset(first, 0, sizeof(first));
    memset(cc, 0, sizeof(cc));
    cnt = 0;
    memset(ans, -1, sizeof(ans));
    for (int i = 1; i <= n; ++i)
        if (d[i] == 0)
            k[i] = 1, ans[i] = 0;
        else
            k[i] = i;
    for (int i = 1; i <= m; ++i) qxx(k[x[i]], k[y[i]], z[i]);
    bfs();
    for (int i = 2; i <= n; ++i) printf("%lld ", ans[i]);
    cout << endl;
    return 0;
}

T3

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
const int N = 1e3 + 11;
int n, a, m;
int jc[N], ny[N];
int c[N][N];
inline int read() {
    int s = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }
    return s;
}
int fm(int x, int y) {
    int ans = 1;
    while (y) {
        if (y & 1)
            ans = ans * x % mod;
        y >>= 1;
        x = x * x % mod;
    }
    return ans;
}
void pre() {
    jc[0] = 1;
    for (int i = 1; i <= 1e3; ++i) {
        jc[i] = jc[i - 1] * i % mod;
        ny[i] = fm(jc[i], mod - 2);
    }
    c[0][0] = 1;
    for (int i = 1; i <= 1e3; ++i)
        for (int j = 0; j <= i; ++j) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
    return;
}
int C(int x, int y) {
    if (y < 0 || x < y)
        return 0;
    return c[x][y];
}
signed main() {
    FILE* x = freopen("legend.in", "r", stdin);
    x = freopen("legend.out", "w", stdout);
    pre();
    n = read();
    m = read();
    a = read();
    int ans = 0;
    for (int i = 0; i <= n; ++i)
        for (int j = 1; j <= a; ++j)
            for (int k = 1; k <= n - i; ++k) {
                if (j * k > m)
                    break;
                int sum1 = 0;
                int h;
                for (int t = 0; t <= i; ++t) {
                    h = m - k * j - t * (j - 1);
                    if (C(h, i) == 0)
                        break;
                    sum1 = (sum1 + fm(mod - 1, t) * C(i, t) % mod * C(h, i)) % mod;
                }
                int sum2 = 0;
                for (int t = k; t <= n - i; ++t) sum2 = (sum2 + c[n - i][t] * fm(a - j, n - i - t)) % mod;
                ans = (ans + c[n][i] * sum1 % mod * sum2) % mod;
            }
    cout << ans * fm(fm(a, n), mod - 2) % mod << endl;
    return 0;
}

T4

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
const int N = 3e3 + 11;
struct qxxx {
    int v, next;
} cc[2 * N];
int n, m, M;
int root;
int ans, sum;
int first[N], cnt;
int son[N], fa[11];
int tmp[N / 3 + 25];
int f[N][N / 3 + 25];
vector<int> vct[11];
inline int read() {
    int s = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }
    return s;
}
void qxx(int u, int v) {
    cc[++cnt] = { v, first[u] };
    first[u] = cnt;
    return;
}
int fm(int x, int y) {
    int as = 1;
    while (y) {
        if (y & 1)
            as = as * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return as;
}
void get_son(int x, int faa) {
    son[x] = 0;
    for (int i = 0; i < vct[x].size(); ++i)
        if (vct[x][i] != faa) {
            fa[vct[x][i]] = x;
            son[x] |= 1 << vct[x][i] - 1;
            get_son(vct[x][i], x);
        }
    return;
}
inline int md(int x) {
    if (x >= mod)
        x -= mod;
    return x;
}
void dfs(int x, int faa) {
    f[x][0] = 1;
    for (int i = first[x]; i; i = cc[i].next)
        if (cc[i].v != faa) {
            dfs(cc[i].v, x);
            memset(tmp, 0, sizeof(tmp));
            for (int j = 1; j <= m; ++j)
                if (fa[j])
                    for (int s = 0, sta = son[fa[j]]; s < M; ++s) {
                        if ((s & sta) != s || ((1 << j - 1) & s))
                            continue;
                        tmp[s | (1 << j - 1)] =
                            md(tmp[s | (1 << j - 1)] + f[x][s] * f[cc[i].v][son[j]] % mod);
                    }
            for (int j = 0; j <= M; ++j) f[x][j] = md(f[x][j] + tmp[j]);
        }
    sum = md(sum + f[x][son[root]]);
    return;
}
void get_tg(int x, int faa) {
    f[x][0] = 1;
    for (int i = 0; i < vct[x].size(); ++i)
        if (faa != vct[x][i]) {
            get_tg(vct[x][i], x);
            memset(tmp, 0, sizeof(tmp));
            for (int j = 1; j <= m; ++j)
                if (fa[j])
                    for (int s = 0, sta = son[fa[j]]; s < M; ++s) {
                        if ((s & sta) != s || ((1 << j - 1) & s))
                            continue;
                        tmp[s | (1 << j - 1)] =
                            md(tmp[s | (1 << j - 1)] + f[x][s] * f[vct[x][i]][son[j]] % mod);
                    }
            for (int j = 0; j <= M; ++j) f[x][j] = md(f[x][j] + tmp[j]);
        }
    sum = md(sum + f[x][son[root]]);
    return;
}
signed main() {
    FILE* x = freopen("count.in", "r", stdin);
    x = freopen("count.out", "w", stdout);
    n = read();
    for (int x, y, i = 1; i < n; ++i) {
        x = read();
        y = read();
        qxx(x, y);
        qxx(y, x);
    }
    M = (1 << (m = read())) - 1;
    for (int x, y, i = 1; i < m; ++i) {
        x = read();
        y = read();
        vct[x].push_back(y);
        vct[y].push_back(x);
    }
    int ans = 0;
    for (int k, i = 1; i <= m; ++i) {
        root = i, sum = 0;
        memset(f, 0, sizeof(f));
        get_son(i, i);
        dfs(1, 1);
        ans = md(ans + sum);
    }
    root = 1, sum = 0;
    get_son(1, 1);
    memset(f, 0, sizeof(f));
    for (int j = 1; j <= m; ++j) {
        memset(f, 0, sizeof(f));
        get_tg(j, j);
    }
    cout << ans * fm(sum, mod - 2) % mod << endl;
    return 0;
}