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
看了一下标签是后缀数据结构,有点慌。题解貌似说是后缀自动机或者后缀树。