Educational Codeforces Round 5

题目链接:https://codeforces.com/contest/616

A - Comparing Two Long Integers

?模拟题,随便搞搞。

B - Dinner with Emma

?模拟题,随便搞搞。

C - The Labyrinth

?模拟题,随便搞搞。

不过要小心计算重复,作为一个1900的选手当然预测到了这一点。

维护连通块的性质,用并查集比用dfs两次遍历要方便。

D - Longest k-Good Segment

一条憨b尺取。但是为什么尺取是对的呢,因为枚举了右端点R,而保持左端点是合法情况下离右端点最远的。

E - Sum of Remainders

简单的数论分块。

题意:求 \(\sum\limits_{i=1}^{m} n%i\)

题解:即 \(\sum\limits_{i=1}^{m} n-\lfloor\frac{n}{i}\rfloor*i\)

\(n*m -\sum\limits_{i=1}^{m}\lfloor\frac{n}{i}\rfloor*i\)

对后面那个进行数论分块。

注意数论分块的写法,是把n/i结果相同的分成一类,首先要保证n/i!=0,否则求r的过程中就会除以零错误,所以l<=min(n,m),而r=min(m,n/(n/l))。

而且对i求和,得到的是一个二次的东西,在中间结果溢出了,实在不好。

ll n, m;

void test_case() {
    scanf("%lld%lld", &n, &m);
    ll ans = n % MOD * (m % MOD) % MOD;
    ll tmp = 0;
    for(ll l = 1, r; l <= min(n, m); l = r + 1) {
        r = min(m, n / (n / l));
        tmp += ((n / l) % MOD) * ((l + r) % MOD) % MOD * ((r - l + 1) % MOD) % MOD * INV2 % MOD;
    }
    ans = (ans - tmp % MOD + MOD) % MOD;
    printf("%lld\n", ans);
}

应该抽象一个S1(ll x)函数,返回从[1,x]的1次方和。

ll n, m;

ll S1(ll x) {
    x %= MOD;
    return (1 + x) * x / 2 % MOD;
}

void test_case() {
    scanf("%lld%lld", &n, &m);
    ll ans = n % MOD * (m % MOD) % MOD;
    ll tmp = 0;
    for(ll l = 1, r; l <= min(n, m); l = r + 1) {
        r = min(m, n / (n / l));
        tmp += (((n / l) % MOD) * ((S1(r) - S1(l - 1) + MOD) % MOD)) % MOD;
    }
    ans = (ans - tmp % MOD + MOD) % MOD;
    printf("%lld\n", ans);
}

F - Expensive Strings

看了一下标签是后缀数据结构,有点慌。题解貌似说是后缀自动机或者后缀树。

posted @ 2020-03-13 04:37  KisekiPurin2019  阅读(129)  评论(0编辑  收藏  举报