20267.25 考试总结

考试总结

估:100 + 100 + 0 + 100

得:100 + 100 + 0 + 100 rk2

666 t4 怎么数据这么水。

状态好拉这 t3 没做出来。

matrix

加强自 Sky Reflector

首先转换充要条件,注意到对于 \(\max_i \{a_i\} \le \min_i \{b_i\}\) 得情况一定能构造出合法矩阵,于是直接计数,枚举 \(b\) 得最小值 \(x\),有:

\[\sum_{x = 1} ^ k x ^ n ((k - x + 1) ^ m - (k - x) ^ m) \]

做完了,用线性筛预处理幂可以做到 \(O(n)\)

code
#include <bits/stdc++.h>
using namespace std;
#define int ll
#define ll long long
#define usd unsigned
#define el putchar('\n')
#define lowbit(x) (x & (-x))
#define AC return 
#define AK return 0
#define YS cout << "YES"
#define NO cout << "NO"
#define Ys cout << "Yes"
#define No cout << "No"
#define ys cout << "yes"
#define no cout << "no"
#define ls(i) ch[i][0]
#define rs(i) ch[i][1]
#define debug(num) cerr << #num << ' ' << num << '\n'
#define void inline void
#define il inline
#define Mod(x) (((x) % mod + mod) % mod)
#define pii pair <int, int>
#define pll pair <ll, ll>
il char gc() { char c; while((c = getchar()) <= ' ') ; return c; }
il int rd() {
	char c; int x, f = 1;
	while(!isdigit(c = getchar())) if(c == '-') f *= -1;
	x = c ^ 48;
	while(isdigit(c = getchar())) x = (x << 3) + (x << 1) + (c ^ 48);
	return x * f;
}
void ACehomoxue();
signed main() {
	srand(time(0));
	// freopen("matrix.in", "r", stdin);
	// freopen("matrix.out", "w", stdout);
	int t = 1;
	// t = rd();
	while(t--) ACehomoxue();
	AK;
}
const int mod = 998244353, maxn = 3 * 1e7 + 18;

int n, m, k, ans = 0;

il int ksm(int a, int k = mod - 2) { int res = 1; for(; k; k >>= 1, a = a * a % mod) if(k & 1) res = res * a % mod; return res; }

vector <int> prime;
bool vis[maxn];
int qpn[maxn], qpm[maxn];
void pre() {
    qpn[1] = qpm[1] = 1;
    for(int i = 2; i < maxn; i++) {
        if(!vis[i]) {
            qpn[i] = ksm(i, n);
            qpm[i] = ksm(i, m);
            prime.push_back(i);
        }
        for(int p : prime) {
            if(i * p >= maxn) break;
            vis[i * p] = true;
            qpn[i * p] = qpn[i] * qpn[p] % mod;
            qpm[i * p] = qpm[i] * qpm[p] % mod;
            if(i % p == 0) break;
        }
    }
}

void ACehomoxue() {
	n = rd(), m = rd(), k = rd();
    if(n == 1) { cout << ksm(k, m); el; AC; }
    if(m == 1) { cout << ksm(k, n); el; AC; }
    pre();
    for(int x = 1, tmp; x <= k; x++) {
        tmp = (qpm[k - x + 1] + mod - qpm[k - x]) % mod * qpn[x] % mod;
        ans = (ans + tmp) % mod;
    }
    cout << ans;
    el;
}

caterpillar

改编自 Tree Queries

我们先考虑暴力,考虑从 \(1\) 开始设计到 \(v\) 的路线,假设确定了在 \(x\) 得子树中,那么若对于 \(x\) 的一个儿子 \(u\) 中最大的关键点深度为 \(mx_u\),那么如果不在 \(u\) 中那么就有 \(k \gets \max(k, mx_u - dep_x)\)。由于 \(k\) 要尽量小那么 \(v\) 就应在 \(mx_u\) 最大的 \(u\) 里,然后再到 \(u\) 的子树中找可以做到 \(O(n ^ 2)\)。考虑这些贡献只和关键点有关,于是拉出虚树做即可。做完了。

code
#include <bits/stdc++.h>
using namespace std;
#define int int
#define ll long long
#define usd unsigned
#define el putchar('\n')
#define lowbit(x) (x & (-x))
#define AC return 
#define AK return 0
#define YS cout << "YES"
#define NO cout << "NO"
#define Ys cout << "Yes"
#define No cout << "No"
#define ys cout << "yes"
#define no cout << "no"
#define ls(i) ch[i][0]
#define rs(i) ch[i][1]
#define debug(num) cerr << #num << ' ' << num << '\n'
#define void inline void
#define il inline
#define Mod(x) (((x) % mod + mod) % mod)
#define pii pair <int, int>
#define pll pair <ll, ll>
il char gc() { char c; while((c = getchar()) <= ' ') ; return c; }
il int rd() {
	char c; int x, f = 1;
	while(!isdigit(c = getchar())) if(c == '-') f *= -1;
	x = c ^ 48;
	while(isdigit(c = getchar())) x = (x << 3) + (x << 1) + (c ^ 48);
	return x * f;
}
void ACehomoxue();
signed main() {
	srand(time(0));
	// freopen("caterpillar.in", "r", stdin);
	// freopen("caterpillar.out", "w", stdout);
	int t = 1;
	// t = rd();
	while(t--) ACehomoxue();
	AK;
}
const int mod = 998244353, maxn = 1e6 + 18, maxk = 21;

int n, q, dep[maxn], in[maxn], dfn, nxt[maxn][maxk];
vector <int> vec[maxn], s;

void dfs(int x, int fa) {
    in[x] = ++dfn;
    dep[x] = dep[fa] + 1;
    nxt[x][0] = fa;
    for(int i = 1; i < maxk; i++) nxt[x][i] = nxt[nxt[x][i - 1]][i - 1];
    for(int to : vec[x]) if(to != fa) dfs(to, x);
}
il int lca(int u, int v) {
    if(dep[u] > dep[v]) swap(u, v);
    for(int i = maxk - 1; i + 1; i--) if(dep[nxt[v][i]] >= dep[u]) v = nxt[v][i];
    if(u == v) return u;
    for(int i = maxk - 1; i + 1; i--) if(nxt[u][i] != nxt[v][i]) u = nxt[u][i], v = nxt[v][i];
    return nxt[u][0];
}

il bool cmp(const int &a, const int &b) { return in[a] < in[b]; }
class vt {
    vector <int> vec[maxn];
    bool vis[maxn];
    int mx[maxn], ans = 0;
    void clr(vector <int> &v) { for(int x : v) vec[x].clear(), vis[x] = false, mx[x] = 0; v.clear(); }
    void pre(int x) {
        for(int to : vec[x]) {
            pre(to);
            mx[x] = max(mx[x], mx[to]);
        }
    }
    void dfs(int x) {
        int fir = 0, sec = 0;
        for(int to : vec[x]) {
            if(mx[to] >= mx[fir]) sec = fir, fir = to;
            else if(mx[to] > mx[sec]) sec = to;
        } 
        if(!fir) AC;
        ans = max(ans, mx[sec] - dep[x]);
        dfs(fir);
    }
public:
    il int sol(vector <int> &p) {
        ans = 0;
        for(int x : p) { vis[x] = true; if(x != 1) mx[x] = dep[x]; }
        sort(p.begin(), p.end(), cmp);
        for(int i = 1, u, v, pa; i < (int) p.size(); i++) {
            u = p[i - 1], v = p[i],  pa = lca(u, v);
            if(!vis[pa]) vis[pa] = true, p.push_back(pa);
        }
        sort(p.begin(), p.end(), cmp);
        for(int i = 1, u, v, pa; i < (int) p.size(); i++) {
            u = p[i - 1], v = p[i], pa = lca(u, v);
            if(pa != v) vec[pa].push_back(v);
        }
        pre(p[0]);
        dfs(p[0]);
        clr(p);
        return ans;
    }
} ds;

void ACehomoxue() {
	n = rd(), q = rd();
    for(int i = 1, u, v; i < n; i++) {
        u = rd(), v = rd();
        vec[u].push_back(v);
        vec[v].push_back(u);
    }
    dfs(1, 0);
    for(int t; q--; ) {
        t = rd();
        s.clear();
        s.push_back(1);
        for(int x; t--; ) {
            x = rd();
            s.push_back(x);
        }
        cout << ds.sol(s);
        el; 
    }
}

/*
g++ -std=c++14 -O2 -o output/caterpillar.exe caterpillar.cpp && cd output && start checker.exe && cd..
*/

nothingness

原:Conveyor

考虑差分第 \(t\) 秒和第 \(t - 1\) 秒计算 \((x, y)\) 上经过的次数来看第 \(t\) 秒是否有史莱姆经过,现在就是求前 \(t\)\((x, y)\) 经过多少次。显然要走 \(x + y\) 次才能到 \((x, y)\),那么只会有 \(t + 1 - x - y\) 个点会有贡献,那么我们令 \(f_{0, 0} = t + 1 - x - y\) 表示可能贡献的经过次数。对于任意的 \(f_{i, j}\),显然其对 \(f_{i + 1, j}\) 的贡献为 \(\lfloor \frac {f_{i, j}} 2 \rfloor\) 而对 \(f_{i, j + 1}\) 贡献有 \(\lceil \frac {f_{i, j}} 2 \rceil\),直接递推到 \(f_{x, y}\) 即可。做完了。

code

training

原:Hysteretic Racing

楼房重建玩耍。考虑直接线段树维护,发现其实维护是简单的,其 push_up() 类似楼房重建的二分,区间修改也都是好维护的。对于查询,我们分两种,一是走到 \(v\) 最大后还能走,直接除一除即可。对于走不到 \(v\) 最大的地方,设位置为 \(p\),那么把 \([s, p]\) 的线段树节点领出来二分即可。

做完了,时间复杂度 \(O(n \log ^ 2n)\)

就是懒得写。

code

posted @ 2026-07-25 15:21  ACehomoxue  阅读(9)  评论(0)    收藏  举报