Author :Zheng_iii

笔者省选打爆了,刚好这场比较简单可以放松一下心情。

A

模拟即可。

void solve()
{
    int x; in >> x;
    if(x <= 1599) out << "Rated\n";
    else out << "Unrated\n";
}

B

把银牌先全换成铜牌,然后再把所有铜牌换成金牌。

void solve()
{
    int a,b,c,x,y; in >> a >> b >> c >> x >> y;
    int req = x * y;
    int S = c + b * x;
    if(S >= req) a += (S - 1) / (req - 1);
    out << a << '\n';
}

C

首先最终序列肯定是单调不增的,我们从大到小往里放。

假设答案是 ,那对于所有位置都满足 ,也就是

不能超过前 的最小值,维护一下 的历史最小值就可以了。

void solve()
{
    int n; in >> n;
    int ans = 0, lim = 2e9;
    rep(i,1,n)
    {
        int d; in >> d;
        ckmin(lim, d + i);
        if(i <= lim) ans = i;
    }
    out << ans << '\n';
}

D

【模板】滑动窗口。

拿两个单调队列维护当前最小值和最大值即可。

void solve()
{
    int n, l = 1; in >> n;
    vi a(n+1);
    std::deque<int> mx, mn;
    int ans = 0;
    rep(i,1,n)
    {
        in >> a[i];
        while(mx.size() && a[mx.back()] <= a[i]) mx.pop_back(); mx.pb(i);
        while(mn.size() && a[mn.back()] >= a[i]) mn.pop_back(); mn.pb(i);
        while(a[mx.front()] - a[mn.front()] > 1)
        {
            if(mx.front() == l) mx.pop_front();
            if(mn.front() == l) mn.pop_front();
            l++;
        }
        ans += i - l + 1;
    }
    out << ans << '\n';
}

E

颅内模拟一下,发现对于有一个 的三元组做一次操作可以复制一个 出来,对于有两个 的三元组做一次操作可以移动一下 的位置,所以只要字符串内有 就可以得到 ,没 显然是 ,全是 显然可以不用操作。

void solve()
{
    int n; std::string s;
    in >> n >> s;
    int cnt = 0;
    for(char c : s) if(c == '1') cnt++;
    if(cnt == 0) out << 0 << '\n';
    else if(cnt == n) out << n << '\n';
    else out << n - 1 << '\n';
}

F

DP,维护 表示前缀可以被划分为多少个方案,维护 表示当前前缀的答案。

void solve()
{
    int n; std::string s; in >> n >> s;
    vi f(n+1),g(n+1),p(n+1);
    f[0] = 1;
    rep(i,0,n-1)
        rep(j,0,i)
        {
            p[j] = (s[j] == s[i]) && (i - j <= 2 || p[j + 1]);
            if(p[j])
            {
                int L = i - j + 1;
                f[i + 1] = (f[i + 1] + f[j]) % mod;
                g[i + 1] = (g[i + 1] + g[j] + f[j] * L % mod * L) % mod;
            }
        }
    out << g[n] << '\n';
}