A - Add and Divide
可以发现,当 $b=2$ 的时候,直接除下去就行,答案不会超过 $\log_2(a)$,然后直接枚举 $b$ 加多少就行,反正不会太大。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
ll a, b;

inline void solve()
{
    cin >> a >> b;
    ll ans = 0;
    if (b == 1)
        ans = llinf;
    else
    {
        ll x = a;
        while (x)
            x /= b, ans++;
    }
    ll now = ans;
    for (int i = 1; i <= ans; ++i)
    {
        b++;
        ll ret = i, x = a;
        while (x)
            x /= b, ret++;
        ans = min(ans, ret);
    }
    cout << ans << endl;
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

B - Replace and Keep Sorted
因为只有一个位置不同,所以每个位置之间的贡献互不影响,设 $ans_i$ 表示第 $i$ 个位置的合法数的区间大小,那么答案就是 $\sum_{i=l}^{r}ans_i$,一个前缀和就搞定。
不过注意两头要特判一下,因为这个时候两头的限制各自少了一边。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n, q, k, a[N];
ll ans[N], sum[N];

inline void solve()
{
    scanf(
    for (int i = 1; i <= n; ++i)
        scanf(
    a[0] = 0, a[n + 1] = k + 1;
    for (int i = 1; i <= n; ++i)
    {
        ans[i] = a[i + 1] - a[i - 1] - 1;
        sum[i] = sum[i - 1] + ans[i];
    }
    while (q--)
    {
        int l, r;
        scanf(
        ll ansnow = sum[r - 1] - sum[l];
        ansnow += a[l + 1] - 1;
        ansnow += k - a[r - 1];
        ansnow = max(0ll, ansnow - (r - l + 1));
        cout << ansnow << '\n';
    }
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    // scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

C - Floor and Mod
这个题还是有点烦的说实话(
其实可以先打个表找下规律(
这里就说规律吧:首先,$(a,a-1)$ 是肯定可以的,然后可以打个表发现对于任何 $(ak,a-1),1\le k \le a-2$ 都是可以的,于是就可以在这上面计算。
可以分成两部分:第一部分是带有 $k\le a-2$ 这个限制的,但是 $a(a-2)\le x$ 的话,$a$ 的上限基本上约等于 $\sqrt{x}$,所以这一部分可以直接 $\mathcal{O}(\sqrt{x})$ 爆算;第二部分的话就没有 $k\le a-2$ 的限制(其实本来也不可能超过上限了),但是有 $ak\le x$ 的限制。可以发现这个能变成 $k\le \lfloor\frac{x}{a}\rfloor$,右边是一个数论分块统计答案。
于是,上面两部分合起来,时间复杂度总的为 $\mathcal{O}(\sqrt{x})$。
但是,比赛的时候我居然不会这个数论分块卡了一个小时......

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
ll x, y;
ll cal(ll n)
{
    ll ans = 0, k = x;
    ll j;
    for (ll i = 1; i <= n; i = j + 1)
    {
        if (!(k / i))
            break;
        j = std::min(k / (k / i), n);
        ans += 1ll * (j - i + 1) * (k / i);
    }
    return ans;
}

inline void solve()
{
    cin >> x >> y;
    ll ans = 0;
    y = min(x - 1, y);
    ll upa = 0;
    while ((upa + 1) * (upa - 1) <= x && upa <= y)
        upa++;
    for (int a = 3; a <= upa; ++a)
        ans += a - 2;
    if (upa == y + 1)
        cout << ans << '\n';
    else
    {
        ans += cal(y + 1) - cal(upa);
        cout << ans << '\n';
    }
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

D - Multiples and Power Differences
这个题挺有意思的(
实际上,构造方法很妙:$\mathrm{lcm}(1,2,3,...,16) = 720720$,这个时候全部变成同一个数了就很好办了:把棋盘黑白染色,黑色块加上原数的四次方即可。
很有意思

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 550;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n, m, k;
int a[N][N], b[N][N];
int _k[N];

inline void solve()
{
    scanf(
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            scanf(
    for (int i = 1; i <= n; ++i, puts(""))
        for (int j = 1; j <= m; ++j)
        {
            if ((i + j) & 1)
                b[i][j] += _k[a[i][j]];
            printf(
        }
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    for (int i = 1;; ++i)
    {
        _k[i] = i * i * i * i;
        if (_k[i] > 1e6)
        {
            k = i - 1;
            break;
        }
    }
    // scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

E - Move and Swap
不难发现 r 和 b 每轮操作结束后一定都在同一层,所以把树上这些点按照层来分类,每一层之间的答案其实没啥影响,设 $dp(u)$ 表示 r=u 时的最大值,接下来分成两种情况算答案:
第一种情况,不交换 r 和 b,那么 b 肯定是选这一层的最大值或者最小值,就在这两者种取 max 就行;
第二种情况,交换 r 和 b,那么可以看成到达 u 的点是 b,这个时候,就要加上上一层的贡献,即从上一层的某个红点到达这一层的红点,即需要满足 $\max{dp_{father_j} + |a_u-a_j|}$,其中 j 和 u 在同一层。这个东西可以维护这一层的 $dp_{father_j}+a_j$ 和 $dp_{father_j}-a_j$ 分别的最大值,这样就变成 $dp(v)=\max{dp(v), \max{dp_{father_j}+a_j-a_u, dp_{father_j}-a_j+a_u }}$(即把绝对值拆开)
最后,答案就是所有点的 dp 值的最大值。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmpfunction) (sort(vecall(v), cmpfunction))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n, dep[N], d;
ll a[N], dp[N], f[N], ans;
vector<int> e[N];
vector<int> vecdep[N];
bool cmp(const int &x, const int &y) { return a[x] < a[y]; }
void data_clear()
{
    d = 0, ans = 0;
    for (int i = 1; i <= n; ++i)
        e[i].resize(0), vecdep[i].resize(0);
    mem(dp, 0, n, ll);
}
void dfsdep(int u, int fa)
{
    dep[u] = dep[fa] + 1, f[u] = fa;
    vecdep[dep[u]].push_back(u), d = max(d, dep[u]);
    for (auto v : e[u])
    {
        if (v == fa)
            continue;
        dfsdep(v, u);
    }
}
queue<int> q;
bool vis[N];
int mxid1[N], mxid2[N];
ll mx1[N], mx2[N];
void work()
{
    mem(vis, 0, d, bool);
    mem(mxid1, -1, d, int), mem(mxid2, -1, d, int);
    fill(mx1 + 1, mx1 + d + 1, -llinf);
    fill(mx2 + 1, mx2 + d + 1, -llinf);
    q.push(1);
    int depth = 2;
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        depth = dep[u] + 1;
        if (!vis[depth])
        {
            vis[depth] = 1;
            for (auto i : vecdep[depth])
            {
                if (dp[f[i]] + a[i] > mx1[depth])
                    mx1[depth] = dp[f[i]] + a[i], mxid1[depth] = i;
                if (dp[f[i]] - a[i] > mx2[depth])
                    mx2[depth] = dp[f[i]] - a[i], mxid2[depth] = i;
            }
        }
        for (auto v : e[u])
        {
            if (dep[v] < depth)
                continue;
            dp[v] = dp[u] + max(abs(a[v] - a[vecdep[depth][0]]), abs(a[v] - a[vecdep[depth].back()]));
            dp[v] = max(dp[v], max(dp[f[mxid1[depth]]] + a[mxid1[depth]] - a[v], dp[f[mxid2[depth]]] - a[mxid2[depth]] + a[v]));
        }
        for (auto v : e[u])
            if (dep[v] == depth)
                q.push(v);
    }
}

inline void solve()
{
    scanf(
    data_clear();
    for (int i = 2; i <= n; ++i)
    {
        int v;
        scanf(
        e[i].push_back(v), e[v].push_back(i);
    }
    for (int i = 2; i <= n; ++i)
        scanf(
    dfsdep(1, 0);
    for (int i = 1; i <= d; ++i)
        veccmpsort(vecdep[i], cmp);
    work();
    for (int i = 1; i <= n; ++i)
    {
        ans = max(ans, dp[i]);
#ifdef VINGYING
        printf(
#endif
    }
#ifdef VINGYING
    puts("");
#endif
    printf(
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}

F - Copy or Prefix Sum
转化一下,$a_i$ 有两种选择:一种是 $b_i$,另一种是 $b_i - \sum_{k=1}^{i-1}a_i$。如果 $\sum_{k=1}^{i-1}a_i = 0$ 的话意味着两种选择相同,我们就需要减去这种情况。
设 $dp(i,j)$ 表示到第 $i$ 个位置的前缀和为 $j$ 的个数,因为到第 $i$ 个位置时前缀和一共差不多有 $i$ 种,借助 map 的话复杂度为 $\mathcal{O}(n^2\log(n))$,因为有两种选择故有两种转移。
考虑优化:实际上,如果 $j=0$ 的话两种转移本质上是相同的,所以此时就需要禁止其中一种转移,这样才能不统计重复,比如禁止第一种转移。那么接下来就要考虑如何计算 $j=0$ 的情况数。
具体可以看代码。

#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\n\nTime used:
    system("pause");
#endif
}
int n;
ll b[N];

inline void solve()
{
    scanf(
    for (int i = 1; i <= n; ++i)
        scanf(
    ll ans = 1;
    map<ll, ll> dp;
    dp[0] = 1;
    ll sum = 0;
    for (int i = 1; i <= n; ++i)
    {
        ll now = dp[sum];
        dp[sum] = ans;sum -= b[i];
        ans = (ans << 1) - now + MOD, ans = (ans + MOD)
    }
    cout << ans << '\n';
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    scanf(
    while (Test--)
    {
        solve();
        // if (Test)
        //     putchar('\n');
    }
    TIME__END = clock();
    program_end();
    return 0;
}