Please subscribe to the official Codeforces channel in Telegram via the link https://t.me/codeforces_official.
×

# | User | Rating |
---|---|---|

1 | tourist | 3707 |

2 | Benq | 3672 |

3 | Radewoosh | 3655 |

4 | ksun48 | 3547 |

5 | jiangly | 3492 |

6 | Miracle03 | 3480 |

7 | ecnerwala | 3400 |

8 | maroonrk | 3385 |

9 | peehs_moorhsum | 3384 |

10 | sunset | 3338 |

# | User | Contrib. |
---|---|---|

1 | 1-gon | 214 |

2 | Um_nik | 190 |

3 | sus | 183 |

4 | YouKn0wWho | 181 |

4 | awoo | 181 |

6 | Errichto | 179 |

7 | tourist | 178 |

8 | -is-this-fft- | 172 |

9 | Radewoosh | 170 |

10 | Ashishgup | 169 |

**오랜만이에요, 코드포스!** (Long time no see, Codeforces!)

I'd like to welcome all of you to Codeforces Round #688 (Div. 2)! The contest will start at Dec/04/2020 16:05 (Moscow time), and it is **rated** for all participants with ratings under 2100. **Note the semi-unusual start time**.

You will be given **6 problems** and **2 hours and 15 minutes** to solve them. The score distribution will be announced soon.

All problems are prepared by me, with a lot of help from the testers ~~making me realize that my solutions are dumb~~.

Thanks to Green55, JooDdae, cs71107, YeongTree, DreamingLeaf, jh05013, Lemonade255, 39dll, alswhp, Ku_Top, sonjaewon, slah007, jooncco, and rkm62 for testing the round, and especially xiaowuc1 for helping polish English statements as well. I would also like to thank 300iq for round coordination, and MikeMirzayanov for the great Codeforces and Polygon system.

See you in the round!

**UPD**: The scoring distribution is **500 — 1000 — 1500 — 2000 — 2500 — 3500**.

**UPD 2**: The round is finished. Thanks for your participation! I'm sorry about underestimating the difficulty of problem B, but I hope you still enjoyed the problems! The editorial will be posted in a minute.

**UPD 3**: The editorial is out!

**UPD 4**: Congratulations to the winners!

**Div. 2**

1: caoyizhong

3: Misaka23334

**Unofficial Div. 1**

1: Geothermal

2: jiangly

3: neal

4: saketh

5: Pyqe

Announcement of Codeforces Round #688 (Div. 2)

I've seen phrases like this in contest announcements many times:

`The score distribution is standard: 500 - 1000 - 1500 - 2000 - 2500 - 3000`

However, I don't really see that this 'standard' distribution is balanced in practice or anything, so I don't get why this uniform distribution is called standard.

The score decreasing rate (i.e. the number of points lost per minute) is proportional to the initial score of the problem. For example, in a 2-hour contest, if you solve a 1000-point problem in 1:59, you get 524 points, which is still higher than solving a 500-problem in 0:00. But if you solve a 3000-point problem in 1:59, you only get 1572 points. That's much less than solving 2000 or 2500-point problem fast enough.

In most of Div. 2 contests, when I see the standings table, the general tendency of gained score of each participant is like this: A <<< B < C >= D >= E >= F. This includes my recent contest (yes, I underestimated D a lot).

I think the reason we give more points to a harder problem is to reward participants who manage to solve those problems. But in practice, a better strategy is to almost always solve easier problems first, and as a result, most people gain less points by solving harder problems. Another side effect is that when you fail on system test, the most critical one is failing on B or C, and not the harder problems. Let's exclude those who first read harder problems and decide to participate only when they're confident to solve it fast.

This is also related to Div. 1 / 2 parallel rounds. I see most of these rounds tend to use score distribution of 2C~2F = 1A~1D + 1000 when these problems are the same ones. But this means Div. 2 participants are rewarded much less for solving 2E or 2F than Div. 1 participants solving 1C or 1D, compared to how much they get for solving 2C(1A) or 2D(1B).

Of course, I didn't count getting wrong answers to get penalty, but the average number of tries to get AC won't be that much to affect this in general.

Conclusively, I'd like to argue that it will be better not to hesitate setting higher score on harder problems. Let me suggest a 'balanced' score distribution I think: 500 — 750 — 1250 — 1750 — 2500 — 3500.

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
int main()
{
int tc;
cin >> tc;
while (tc--)
{
int x, y, a, b;
cin >> x >> y >> a >> b;
cout << ((y - x) % (a + b) == 0 ? (y - x) / (a + b) : -1) << endl;
}
}
```

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 100;
string s[MAX_N];
int main()
{
set<string> dict;
int n, m, i;
cin >> n >> m;
for (i = 0; i < n; i++)
{
cin >> s[i];
dict.insert(s[i]);
}
vector<string> left, right;
string mid;
for (i = 0; i < n; i++)
{
string t = s[i];
reverse(t.begin(), t.end());
if (t == s[i])
mid = t;
else if (dict.find(t) != dict.end())
{
left.push_back(s[i]);
right.push_back(t);
dict.erase(s[i]);
dict.erase(t);
}
}
cout << left.size() * m * 2 + mid.size() << endl;
for (string x : left)
cout << x;
cout << mid;
reverse(right.begin(), right.end());
for (string x : right)
cout << x;
cout << endl;
}
```

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 100;
int t[MAX_N], lo[MAX_N], hi[MAX_N];
int main()
{
int tc;
cin >> tc;
while (tc--)
{
int n, m, i;
cin >> n >> m;
for (i = 0; i < n; i++)
cin >> t[i] >> lo[i] >> hi[i];
int prev = 0;
int mn = m, mx = m;
bool flag = true;
for (i = 0; i < n; i++)
{
mx += t[i] - prev;
mn -= t[i] - prev;
if (mx < lo[i] || mn > hi[i])
{
flag = false;
break;
}
mx = min(mx, hi[i]);
mn = max(mn, lo[i]);
prev = t[i];
}
if (flag)
cout << "YES\n";
else
cout << "NO\n";
}
}
```

1304D — Shortest and Longest LIS

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 200000;
int ans[MAX_N + 5];
int main()
{
int tc;
cin >> tc;
while (tc--)
{
int n, i, j;
string s;
cin >> n >> s;
int num = n, last = 0;
for (i = 0; i < n; i++)
{
if (i == n - 1 || s[i] == '>')
{
for (j = i; j >= last; j--)
ans[j] = num--;
last = i + 1;
}
}
for (i = 0; i < n; i++)
cout << ans[i] << (i == n - 1 ? '\n' : ' ');
num = 1, last = 0;
for (i = 0; i < n; i++)
{
if (i == n - 1 || s[i] == '<')
{
for (j = i; j >= last; j--)
ans[j] = num++;
last = i + 1;
}
}
for (i = 0; i < n; i++)
cout << ans[i] << (i == n - 1 ? '\n' : ' ');
}
}
```

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 100000;
const int LIM = 17;
const int INF = (int)1e9 + 7;
vector<int> adj[MAX_N + 5];
int depth[MAX_N + 5];
int par[MAX_N + 5][LIM + 1];
void build(int cur, int p)
{
int i;
depth[cur] = depth[p] + 1;
par[cur][0] = p;
for (i = 1; i <= LIM; i++)
par[cur][i] = par[par[cur][i - 1]][i - 1];
for (int x : adj[cur])
if (x != p)
build(x, cur);
}
int lca_len(int a, int b)
{
int i, len = 0;
if (depth[a] > depth[b])
swap(a, b);
for (i = LIM; i >= 0; i--)
{
if (depth[par[b][i]] >= depth[a])
{
b = par[b][i];
len += (1 << i);
}
}
if (a == b)
return len;
for (i = LIM; i >= 0; i--)
{
if (par[a][i] != par[b][i])
{
a = par[a][i];
b = par[b][i];
len += (1 << (i + 1));
}
}
return len + 2;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, q, i;
cin >> n;
for (i = 0; i < n - 1; i++)
{
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
build(1, 0);
cin >> q;
while (q--)
{
int x, y, a, b, k;
cin >> x >> y >> a >> b >> k;
int without = lca_len(a, b);
int with = min(lca_len(a, x) + lca_len(y, b), lca_len(a, y) + lca_len(x, b)) + 1;
int ans = INF;
if (without % 2 == k % 2)
ans = without;
if (with % 2 == k % 2)
ans = min(ans, with);
cout << (ans <= k ? "YES" : "NO") << '\n';
}
}
```

1304F1 — Animal Observation (easy version)

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 50;
const int MAX_M = 20000;
const int MAX_K = 20;
int animal[MAX_N + 5][MAX_M + 5];
int psum[MAX_N + 5][MAX_M + 5];
int lmax[MAX_N + 5][MAX_M + 5];
int rmax[MAX_N + 5][MAX_M + 5];
int dp[MAX_N + 5][MAX_M + 5];
inline int ps(int i, int j, int k)
{
return psum[i][k] - psum[i][j - 1];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int i, j;
int n, m, k;
cin >> n >> m >> k;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
cin >> animal[i][j];
psum[i][j] = psum[i][j - 1] + animal[i][j];
}
}
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m - k + 1; j++)
{
int p = ps(i, j, j + k - 1) + ps(i + 1, j, j + k - 1);
if (i == 1)
{
dp[i][j] = p;
continue;
}
int mx = 0;
for (int x = max(1, j - k + 1); x <= min(m - k + 1, j + k - 1); x++)
mx = max(mx, dp[i - 1][x] + p - ps(i, max(x, j), min(x + k - 1, j + k - 1)));
dp[i][j] = mx;
if (j > k)
dp[i][j] = max(dp[i][j], lmax[i - 1][j - k] + p);
if (j + k - 1 <= m - k)
dp[i][j] = max(dp[i][j], rmax[i - 1][j + k] + p);
}
for (j = 1; j <= m - k + 1; j++)
lmax[i][j] = max(lmax[i][j - 1], dp[i][j]);
for (j = m - k + 1; j >= 1; j--)
rmax[i][j] = max(rmax[i][j + 1], dp[i][j]);
}
cout << *max_element(dp[n] + 1, dp[n] + m + 1) << '\n';
}
```

1304F2 — Animal Observation (hard version)

Tutorial is loading...

```
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 50;
const int MAX_M = 20000;
const int MAX_K = 20;
int animal[MAX_N + 5][MAX_M + 5];
int psum[MAX_N + 5][MAX_M + 5];
int dp[MAX_N + 5][MAX_M + 5];
int t[MAX_M * 4], lazy[MAX_M * 4];
void update_lazy(int i, int lo, int hi)
{
if (lazy[i])
{
t[i] += lazy[i];
if (lo != hi)
{
lazy[i * 2] += lazy[i];
lazy[i * 2 + 1] += lazy[i];
}
lazy[i] = 0;
}
}
int update(int i, int lo, int hi, int l, int r, int val)
{
update_lazy(i, lo, hi);
if (lo > r || hi < l)
return t[i];
if (l <= lo && hi <= r)
{
t[i] += val;
if (lo != hi)
{
lazy[i * 2] += val;
lazy[i * 2 + 1] += val;
}
return t[i];
}
int mid = (lo + hi) / 2;
return t[i] = max(update(i * 2, lo, mid, l, r, val), update(i * 2 + 1, mid + 1, hi, l, r, val));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int i, j;
int n, m, k;
cin >> n >> m >> k;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
cin >> animal[i][j];
psum[i][j] = psum[i][j - 1] + animal[i][j];
}
}
int mm = m - k + 1;
for (i = 1; i <= mm; i++)
dp[1][i] = psum[1][i + k - 1] - psum[1][i - 1] + psum[2][i + k - 1] - psum[2][i - 1];
for (i = 2; i <= n; i++)
{
memset(t, 0, sizeof t);
memset(lazy, 0, sizeof lazy);
for (j = 1; j <= mm; j++)
update(1, 1, mm, j, j, dp[i - 1][j]);
for (j = 1; j <= k; j++)
update(1, 1, mm, 1, j, -animal[i][j]);
for (j = 1; j <= mm; j++)
{
dp[i][j] = t[1] + psum[i][j + k - 1] - psum[i][j - 1] + psum[i + 1][j + k - 1] - psum[i + 1][j - 1];
if (j != mm)
{
update(1, 1, mm, max(1, j - k + 1), j, animal[i][j]);
update(1, 1, mm, j + 1, j + k, -animal[i][j + k]);
}
}
}
cout << *max_element(dp[n] + 1, dp[n] + mm + 1) << endl;
}
```

```
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
const int MAX_N = 50;
const int MAX_M = 20000;
const int MAX_K = 20;
int n, m, k;
inline int ps(vvi &p, int i, int s, int e)
{
if (s < 1)
return p[i][e];
return p[i][e] - p[i][s - 1];
}
void calc_overlapped(vvi &ar, vvi &p, vvi &dp, int i)
{
int j;
deque<pii> dq;
for (j = 1; j <= m - k + 1; j++)
{
int num = dp[i - 1][j] - ps(p, i, j, j + k - 1);
if (dq.size() && dq.front().second <= j - k)
dq.pop_front();
while (dq.size() && dq.back().first + ps(p, i, dq.back().second, j - 1) <= num)
dq.pop_back();
dq.push_back({ num, j });
dp[i][j] = dq.front().first + ps(p, i, dq.front().second, j - 1) + ps(p, i, j, j + k - 1) + ps(p, i + 1, j, j + k - 1);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int i, j;
cin >> n >> m >> k;
vvi init(n + 5, vi(m + 5, 0));
vvi animal, animal_rev, psum, psum_rev, lmax, rmax, dp, dpl, dpr;
animal = animal_rev = psum = psum_rev = lmax = rmax = dp = dpl = dpr = init;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
cin >> animal[i][j];
psum[i][j] = psum[i][j - 1] + animal[i][j];
animal_rev[i][m - j + 1] = animal[i][j];
}
for (j = 1; j <= m; j++)
psum_rev[i][j] = psum_rev[i][j - 1] + animal_rev[i][j];
}
deque<pii> dq;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m - k + 1; j++)
{
if (j > k)
dp[i][j] = lmax[i - 1][j - k];
if (j <= m - k * 2 + 1)
dp[i][j] = max(dp[i][j], rmax[i - 1][j + k]);
dp[i][j] += ps(psum, i, j, j + k - 1) + ps(psum, i + 1, j, j + k - 1);
}
calc_overlapped(animal, psum, dpl, i);
calc_overlapped(animal_rev, psum_rev, dpr, i);
for (j = 1; j <= m - k + 1; j++)
{
dp[i][j] = max({ dp[i][j], dpl[i][j], dpr[i][m - j - k + 2] });
dpl[i][j] = dpr[i][m - j - k + 2] = dp[i][j];
}
for (j = 1; j <= m - k + 1; j++)
lmax[i][j] = max(lmax[i][j - 1], dp[i][j]);
for (j = m - k + 1; j >= 1; j--)
rmax[i][j] = max(rmax[i][j + 1], dp[i][j]);
}
cout << *max_element(dp[n].begin(), dp[n].end()) << endl;
}
```

Tutorial of Codeforces Round #620 (Div. 2)

**안녕하세요, 코드포스!** (Hello, Codeforces!)

I'm glad to invite you to Codeforces Round #620 (Div. 2). The contest will start at Feb/15/2020 16:05 (Moscow time), and it is **rated** for all participants with ratings under 2100.

You will be given **6 problems** and one of the problems has 2 subtasks. The contest duration is **2 hours**. The score distribution will be announced later.

All problems are prepared by me, with huge help from the testers with developing great solutions.

I'll be on the community Discord server after the contest to share my thoughts and get feedback about the problems.

Thanks to 79brue, molamola., DreamingLeaf, evenharder, cs71107, Justice_Hui, rkm0959, chpark1111, imeimi, alswhp, gaelim, jh05013 (Good tester), yuto0518, N_jara, aryanc403, SnowGoose, TheDramaQueen, surung9898, and ko_osaga for testing the round. I would also like to thank 300iq for round coordination, and MikeMirzayanov for the great Codeforces and Polygon system.

Hope you enjoy the problems!

**UPD**: The scoring distribution is 500 — 1000 — 1500 — 1750 — 2000 — (2000 + 1000)

**UPD2**: The contest is finished! Thanks so much for your participation! The editorial is here.

**UPD3**: Congratulations to the winners!

**Div. 2**

2: COVID-19

3: naive_xay

4: dargelirli

5: ChitandaEru

**Unofficial Div. 1**

1: wucstdio

2: ksun48

3: jiangly

4: uwi

5: teapotd

Announcement of Codeforces Round #620 (Div. 2)

The problems with Gildong (B, D, F) are by me, and Amugae (A, C, E) are by no_ng.

Tutorial is loading...

Tutorial is loading...

Tutorial is loading...

Tutorial is loading...

Tutorial is loading...

Tutorial is loading...

Tutorial of Codeforces Round #578 (Div. 2)

**안녕하세요, 코드포스!** (Hello, Codeforces!)

We're glad to introduce you to Codeforces Round #578 (Div. 2), which will start at Aug/11/2019 15:35 (Moscow time). The round is **rated** for Div. 2 participants.

You will be given **6 problems** and **2 hours** to solve them. The score distribution will be announced later.

The problems are prepared by no_ng and me.

Thanks to pllk, Learner99, Rox, mohammedehab2002, cheetose, jh05013, rkm0959, edenooo, and alex9801 for testing the round. We would also like to specially thank to KAN and arsijo for coordinating the round, and of course, MikeMirzayanov for Codeforces and Polygon platform.

This is our very first round, so I hope you enjoy it a lot!

**UPD**: The scoring distribution is 500 — 1000 — 1250 — 2000 — 2000 — 2500

**UPD2**: The contest is finished. Thanks for joining us! Here's the editorial.

**UPD3**: Congratulations to the winners!

**Div. 2**

2: oliviahye

3: ccf_n0i

4: 2om_neek

**Unofficial Div. 1**

1: kcm1700

2: uwi

3: square1001

4: kmjp

5: KrK

Announcement of Codeforces Round #578 (Div. 2)

Currently, any successful hacks on any problem provide exactly 100 points. For problem A and B it seems quite reasonable, but I find it barely motivating to lock harder problems and try to hack (unless it's known that the pretests are exceptionally weak), since:

- You risk losing a lot of points on system test. Even if you realize mistakes in your code after lock, you can't do anything.
- There are (usually) not many solutions to look into in your room in the first place.
- Harder problems (usually) require hard techniques and longer implementation, so reading each solution takes a lot of time.
- Even if you successfully hack, 100 points don't affect your rank too much.

Rewarding more points for hacking solutions for harder problems would make the system more interesting and balanced. My suggestion is to reward 1/10 of the problem's score for successful hacks. i.e. 50 points for hacking a solution of a 500-point problem, and 200 points for hacking a 2000-point problem.

Here are some reasons for the suggestion:

- Hacking solutions of a hard problem requires you to understand the hard problem itself, high-level logic behind the codes, and complicated implementations.
- There are usually more pretests on harder problems, so the chance of passing all pretests on harder problems with a wrong solution is already low.
- Currently hacks are mostly only for easier problems. If people would be motivated to lock harder problems too, that would make the use of hacks more balanced.
- It may seem that 300 points for hacking one solution is too much. But this implies that the contestant has solved (or at least, passed pretests) a 3000-point problem. For example in Codeforces Round #509 (Div. 2), if you solved all problems and have 7700 points, you would be at rank 33. Even if you successfully hack a solution on F, you would be only at rank 25. On the other hand, if you solved problem A only and have 450 points, then you hack a solution on A, your rank will be: 4410 -> 4062.
- For easier problems you usually read a lot of solutions written by people new to problem solving. Solutions for harder problems are mostly written by good coders and reading them itself helps you study as well.
- It can be seen as an additional reward for passing pretests of a hard problem.

Of course, this is just my opinion and I know it has a lot of disadvantages as well, but I just want to share ideas and imagine how codeforces contests would be with a different hack system. Any other opinions are appreciated.

Codeforces (c) Copyright 2010-2021 Mike Mirzayanov

The only programming contests Web 2.0 platform

Server time: Sep/21/2021 09:24:35 (h1).

Desktop version, switch to mobile version.

Supported by

User lists

Name |
---|