[题解]嘉然今天晚上吃点好的

\[\color{red}{\text{校长者,真神人也,左马桶,右永神,会执利笔破邪炁,何人当之?}} \\ \begin{array}{|} \hline \color{pink}{\text{The principal is really a god}} \\ \color{pink}{\text{with a closestool on the left and Yongshen on the right}} \\ \color{pink}{\text{holding a sharp pen to pierce the truth}} \\ \color{pink}{\text{Who can resist him? }} \\ \hline \end{array} \\ \begin{array}{|} \hline \color{green}{\text{校長は本当に神であり、左側にトイレ、右側にヨンシェンがあり}} \\ \color{green}{\text{鋭いペンを持って真実を突き刺している。誰が彼に抵抗できるだろうか? }} \\ \hline \end{array} \\ \begin{array}{|} \hline \color{lightblue}{\text{Le principal est vraiment un dieu}} \\ \color{lightblue}{\text{avec des toilettes à gauche et Yongshen à droite}} \\ \color{lightblue}{\text{tenant un stylo pointu pour percer la vérité}} \\ \color{lightblue}{\text{Qui peut lui résister ? }} \\ \hline \end{array} \\ \begin{array}{|} \hline \color{purple}{\text{Der Direktor ist wirklich ein Gott}} \\ \color{purple}{\text{mit einer Toilette links und Yongshen rechts}} \\ \color{purple}{\text{der einen spitzen Stift hält}} \\ \color{purple}{\text{um die Wahrheit zu durchdringen.}} \\ \color{purple}{\text{Wer kann ihm widerstehen? }} \\ \hline \end{array} \\ \begin{array}{|} \hline \color{cyan}{\text{Principalis deus est, Yongshen a dextris cum latrina}} \\ \color{cyan}{\text{acuto stylo ad perforandum veritatem: quis resistet ei? }} \\ \hline \end{array} \\ \color{red}{\text{对曰:“无人,狗欲当之,还请赐教!”}} \\ \newcommand\brak[1]{\left({#1}\right)} \newcommand\Brak[1]{\left\{{#1}\right\}} \newcommand\d[0]{\text{d}} \newcommand\string[2]{\genfrac{\{}{\}}{0pt}{}{#1}{#2}} \newcommand\down[2]{{#1}^{\underline{#2}}} \newcommand\ddiv[2]{\left\lfloor\frac{#1}{#2}\right\rfloor} \newcommand\udiv[2]{\left\lceil\frac{#1}{#2}\right\rceil} \newcommand\lcm[0]{\operatorname{lcm}} \newcommand\set[1]{\left\{{#1}\right\}} \newcommand\ceil[1]{\left\lceil{#1}\right\rceil} \newcommand\floor[1]{\left\lfloor{#1}\right\rfloor} \newcommand\rhs[1]{\;\text{Rhs}\;#1} \newcommand\lhs[1]{\;\text{Lhs}\;#1} \newcommand\Vec[1]{\vec{\mathbf{#1}}} \newcommand\rank[0]{\text{rank}} \]




  \(\mathcal{Back\;To\;The\;Menu}\).

2022-03-03 嘉然今天晚上吃点好的

  本来只给第二题分配了一个半小时,结果一直调到考试结束......

矩形 / Rectangle

  建笛卡尔树,然后想怎么搞怎么搞。

/** @author __Elaina__ */

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
#include <cassert>

namespace Elaina {
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
/** @warning no forced type conversion */
#define rqr(x) ((x) * (x))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER

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

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void chkmin(T& x, const T rhs) { x = std::min(x, rhs); }
template<class T> inline void chkmax(T& x, const T rhs) { x = std::max(x, rhs); }
template<class T> inline void myswap(T& x, T& y) { x ^= y ^= x ^= y; }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI getchar()
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}

} // namespace Elaina
using namespace Elaina;

const int Maxn = 1e5;
const int Mod = 1e9 + 7;
const int inv2 = 500000004;
inline void chkadd(int& x, int y) { if ((x += y) >= Mod) x -= Mod; }

int h[Maxn + 5], w[Maxn + 5], n;

inline void input() {
    readin(n);
    rep (i, 1, n) readin(h[i]);
    rep (i, 1, n) readin(w[i]);
}

int lson[Maxn + 5], rson[Maxn + 5];
int stk[Maxn + 5], tl;
inline void buildTree() {
    rep (i, 1, n) {
        while (tl && h[stk[tl]] >= h[i]) lson[i] = stk[tl--];
        if (stk[tl]) rson[stk[tl]] = i;
        stk[++tl] = i;
    }
}

int f[Maxn + 5];
void dfs(int u) {
    if (lson[u]) dfs(lson[u]), chkadd(f[u], f[lson[u]]);
    if (rson[u]) dfs(rson[u]), chkadd(f[u], f[rson[u]]);
    int tmp = 1ll * h[u] * (h[u] + 1) % Mod * inv2 % Mod;
    if (lson[u]) chkadd(f[u], 1ll * w[lson[u]] * w[u] % Mod * tmp % Mod);
    if (rson[u]) chkadd(f[u], 1ll * w[rson[u]] * w[u] % Mod * tmp % Mod);
    if (lson[u] && rson[u])
        chkadd(f[u], 1ll * w[lson[u]] * w[rson[u]] % Mod * tmp % Mod);
    chkadd(f[u], 1ll * w[u] * (w[u] + 1) % Mod * inv2 % Mod * tmp % Mod);
    chkadd(w[u], (w[lson[u]] + w[rson[u]]) % Mod);
}

signed main() {
    freopen("rectangle.in", "r", stdin);
    freopen("rectangle.out", "w", stdout);
    input();
    buildTree();
    dfs(stk[1]);
    writln(f[stk[1]]);
    return 0;
}

[CEOI2020]星际迷航 / Tree

  虽然一看就是矩阵加速......

  如果 \(D=0\)(虽然没有),就是一个很明显的 DP 了,可以设 \(sg(i)\) 表示 \(i\) 点的 SG 函数值,那么有转移

\[sg(u)=\bigcup_{v\in son(u)}(sg(v)\oplus 1) \]

  当 \(D=1\),有了一个副本,而通过传送门走到下一个副本的点 \(x\),实际上就是以 \(x\) 为根做上面的东西,因此很明显我们需要换根。

  有了上面的铺垫,你会发现接一个传送门,实际上是给原来的树上的某个点接上一个 \(sg\)\(0\) 或者 \(1\) 的儿子,而该儿子在下一个副本将被视为根,也就是说,我们实际上关注的重点始终都是副本的根的状态,而不在意当点不为根时的状态,所以我们可以设计一个状态:\(f(i,0/1)\) 表示考虑到副本 \(i\),使得根的状态最终为 \(0/1\) 的方案数。

  显然,求出初始的 \(f(D,0/1)\) 需要我们实现一个换根 DP,而从一个副本转移到另外一个副本呢?

  由于 “接一个传送门,实际上是给原来的树上的某个点接上一个 \(sg\)\(0\) 或者 \(1\) 的儿子”,而根据上面的 \(sg\) 转移,又发现接上一个 \(sg=1\) 的儿子好像对整棵树没啥影响,但是接上一个为 \(0\) 的儿子,对其父亲,乃至根可能都有影响。因此,我们对于转移有了一个大概的思路,先对当前的点最终状态是 \(0\) 还是 \(1\) 进行分类,假如当前的点最终是 \(0\),那么有两种情况:本身就是 \(0\),或者本来是 \(1\),但是树中的某个点翻转之后影响到它了,设 \(sg(u)\) 表示没有进行任何修改时,点 \(u\)\(sg\) 函数值,那么就有

\[\begin{aligned} f(i,0)&=\sum_{sg(u)=1}flip(u)\times f(i+1,0)+\sum_{sg(u)=0}n\times f(i+1,1) \\ &=Fp(1)\times f(i+1,0)+n\times loss\times f(i+1,1) \end{aligned} \]

  其中 \(flip(u)\) 为当 \(u\) 是根时,有多少原必败点翻转后会影响到它(你无法让必胜点翻转),而 \(\displaystyle Fp(t)=\sum_{sg(u)=t}flip(u)\)\(\displaystyle loss=\sum [sg(u)=0]\),同样,我们可以发现 \(f(i,1)\) 的转移:

\[\begin{aligned} f(i,1)&=\sum_{sg(u)=0}flip(u)\times f(i+1,0)+\sum_{sg(u)=1}n\times f(i+1,1) \\ &=Fp(0)\times f(i+1,0)+n\times win\times f(i+1,1) \end{aligned} \]

  其中 \(win\) 的定义和 \(loss\) 相反。

  不难发现,转移中 \(Fp(),n,win,loss\) 这些系数都是固定的,因此可以直接矩阵加速转移,时间复杂度 \(\mathcal O(n+\log_2 D\times 2^3)\).

  因为找不到草稿纸了所以不知道转移是否写错了,如有写错请指出。

/** @author __Elaina__ */

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
#include <cassert>

namespace Elaina {
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
/** @warning no forced type conversion */
#define rqr(x) ((x) * (x))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER

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

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void chkmin(T& x, const T rhs) { x = std::min(x, rhs); }
template<class T> inline void chkmax(T& x, const T rhs) { x = std::max(x, rhs); }
template<class T> inline void myswap(T& x, T& y) { x ^= y ^= x ^= y; }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI getchar()
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}

} // namespace Elaina
using namespace Elaina;

// #define int long long

const int Mod = 1e9 + 7;
const int Maxn = 1e5;
inline void chkadd(int& x, int y) { if ((x += y) >= Mod) x -= Mod; }

int n; ll D;
vector<int> g[Maxn + 5];

struct matrix {
    int c[2][2];
    inline matrix() { memset(c, 0, sizeof c); }
    inline matrix operator *(const matrix& rhs) {
        matrix ret;
        for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j)
            for (int k = 0; k < 2; ++k)
                chkadd(ret.c[i][k], 1ll * c[i][j] * rhs.c[j][k] % Mod);
        return ret;
    }
    inline void print() {
        for (int i = 0; i < 2; ++i) {
            for (int j = 0; j < 2; ++j)
                writln(c[i][j], ' ');
            Endl;
        }
    }
};
inline matrix qkpow(matrix a, ll q) {
    matrix ret;
    for (int i = 0; i < 2; ++i) ret.c[i][i] = 1;
    for (; q; q >>= 1, a = a * a) if (q & 1) ret = ret * a;
    return ret;
}

inline void input() {
    readin(n, D);
    int u, v;
    rep (i, 2, n) {
        readin(u, v);
        g[u].push_back(v), g[v].push_back(u);
    }
}

int sg[Maxn + 5], cnt[Maxn + 5][2];
int dp[Maxn + 5][2]; ///< sum[][1] is for all
int flip[Maxn + 5];
inline void update(int u) {
    flip[u] = 0;
    if (sg[u]) {
        if (cnt[u][0] == 1) flip[u] = dp[u][0];
    }
    else flip[u] = dp[u][1]; // flip a son can change everything
}
void dfs1(int u, int par) {
    for (const int& v: g[u]) if (v ^ par)
        dfs1(v, u), ++cnt[u][sg[v]];
    sg[u] = !!cnt[u][0];
    for (const int& v: g[u]) if (v ^ par) {
        dp[u][1] += flip[v] + (!sg[v]);
        if (!sg[v]) dp[u][0] += flip[v] + 1;
    }
    update(u);
}

int sum[2], win;
void dfs2(int u, int par) {
    int _sg, _fli, _cnt[2], _dp[2];
    _sg = sg[u], _fli = flip[u];
    memcpy(_cnt, cnt[u], sizeof _cnt);
    memcpy(_dp, dp[u], sizeof _dp);
    win += _sg, chkadd(sum[_sg], _fli);

    if (!_sg) chkadd(sum[_sg], 1);
    for (const int& v: g[u]) if (v ^ par) {
        --cnt[u][sg[v]];
        if (!sg[v]) dp[u][0] -= flip[v] + 1;
        dp[u][1] -= flip[v] + (!sg[v]);
        sg[u] = !!cnt[u][0];
        update(u);

        ++cnt[v][sg[u]];
        if (!sg[u]) dp[v][0] += flip[u] + 1;
        dp[v][1] += flip[u] + (!sg[u]);
        sg[v] = !!cnt[v][0];
        update(v);

        dfs2(v, u);

        sg[u] = _sg, flip[u] = _fli;
        memcpy(cnt[u], _cnt, sizeof _cnt);
        memcpy(dp[u], _dp, sizeof _dp);
    }
}

matrix acc, a;

signed main() {
    // freopen("tree.in", "r", stdin);
    // freopen("tree.out", "w", stdout);
    input();
    dfs1(1, 0);
    dfs2(1, 0);
    // fprintf(stderr, "sum[0] == %d, sum[1] == %d\n", sum[0], sum[1]);
    // fprintf(stderr, "win == %d\n", win);
    acc.c[0][0] = (1ll * (n - win) * n % Mod + Mod - sum[0] + sum[1]) % Mod;
    acc.c[0][1] = 1ll * (n - win) * n % Mod;
    acc.c[1][1] = 1ll * win * n % Mod;
    acc.c[1][0] = (1ll * win * n % Mod + Mod - sum[1] + sum[0]) % Mod;
    // acc.print();
    a.c[0][0] = n - win, a.c[1][0] = win;
    a = qkpow(acc, D - 1) * a;
    // a.print();
    int t0 = a.c[0][0], t1 = a.c[1][0], ans = 0;
    if (sg[1])
        ans = (1ll * (n - flip[1]) * (t0 + t1) % Mod + 1ll * flip[1] * t1 % Mod) % Mod;
    else ans = 1ll * (flip[1] + 1) * t0 % Mod;
    writln(ans);
    return 0;
}
/**
 * 
 * @p D is too large -> use matrix to accelerate DP transfer
 * 
 * When @p D == 0, tree DP is enough
 *      sg(u) = \Or_{v is the son of u} (sg(v) ^ 1)
 * 
 * When @p D == 1
 *      root-changing DP?
 *      regard the first node we reach on the second tree as the root
 *      and run the game
 * 
 * pay attention to that "root" is the key
 * the only thing that we need to care about is the value of sg() of the root
 * 
 * define f(i, s):
 *      the number of ways
 *      to make the root of tree @p i satisfy sg(root) = @p s
 * 
 * a question that some points' changing may affect the state of root
 * use root-changing DP to solve it!
 * 
*/

排序 / Sort

  这个题实际上和 <2022-02-26 可恶!然而......:排队 / Queue> 是一样的,因为,存在这样一个等式......

\[\frac{1}{2}\sum_{i=1}^n|i-p_i|=\sum_{i=1}^n\max(i-p_i,0) \]

  因此,需要满足的结论也应当是一样的,即 \(\max(i-p_i,0)=d(i)\),然后就有个同样的结论:要么前面没有比它大的(\(i<p_i\)),要么比它小的全在它前面(\(i>p_i\)),然后设计 DP 状态,\(f(i,j)\) 表示当前位置是 \(i\),前面的数字集合的最大值为 \(j\) 时的方案数,那么有

\[f(i,j)=f(i-1,j)+\sum_{k<j}f(i-1,k) \]

  同样的前缀和,就有

\[g(i,j)=g(i-1,j)+g(i,j-1) \\ g(0,0)=1 \]

  看似又归约到卡塔兰数的问题上,但是有个问题:如何比较字典序?实际上很简单,用类似数位 DP 的方法做即可,即我们每次贴近一个前缀,然后统计从枚举的这个位置 \(i\) 开始 “出超” 的方案数,因为 “出超” 之后就不受 \(p\) 的限制而只受 \(y=x\) 的限制,因此可以直接用卡塔兰数来算,实际上和 <排队> 是一样的,钦定前缀进行计算。时间复杂度 \(\mathcal O(n)\).

/** @author __Elaina__ */

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
#include <cassert>

namespace Elaina {
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
/** @warning no forced type conversion */
#define rqr(x) ((x) * (x))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER

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

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void chkmin(T& x, const T rhs) { x = std::min(x, rhs); }
template<class T> inline void chkmax(T& x, const T rhs) { x = std::max(x, rhs); }
template<class T> inline void myswap(T& x, T& y) { x ^= y ^= x ^= y; }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI getchar()
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}

} // namespace Elaina
using namespace Elaina;

const int Mod = 998244353;
const int Maxn = 2000000;

inline void chkadd(int& x, int y) { if ((x += y) >= Mod) x -= Mod; }

int fac[Maxn + 5], inv[Maxn + 5], finv[Maxn + 5];
inline void prelude() {
    fac[0] = fac[1] = inv[0] = inv[1] = finv[0] = finv[1] = 1;
    rep (i, 2, Maxn) {
        fac[i] = 1ll * fac[i - 1] * i % Mod;
        inv[i] = 1ll * (Mod - Mod / i) * inv[Mod % i] % Mod;
        finv[i] = 1ll * finv[i - 1] * inv[i] % Mod;
    }
}
inline int C(int n, int m) {
    if (n < m || n < 0 || m < 0) return 0;
    return 1ll * fac[n] * finv[n - m] % Mod * finv[m] % Mod;
}
inline int cata(int n, int m) {
    return (C(n + m, m) + Mod - C(n + m, m - 1)) % Mod;
}

int p[Maxn + 5], n;
bool used[Maxn + 5];

inline void solve() {
    readin(n);
    rep (i, 1, n) readin(p[i]);
    int mex = 1, mx = 0, ans = 0;
    memset(used + 1, false, n);
    rep (i, 1, n) {
        int y = max(mx + 1, p[i] + 1);
        used[p[i]] = true;
        if (y <= n) chkadd(ans, cata(n - i + 1, n - y));
        if (mx < p[i]) mx = p[i];
        else if (p[i] != mex) break;
        while (used[mex]) ++mex;
    }
    writln(ans);
}

signed main() {
    freopen("sort.in", "r", stdin);
    freopen("sort.out", "w", stdout);
    prelude();
    rep (_, 1, readret(1)) solve();
    return 0;
}
posted @ 2022-03-14 22:09  Arextre  阅读(71)  评论(0编辑  收藏  举报