Gerald's blog

By Gerald13 days ago, translation, In English

Good Morning, Codeforces!

Analyzing the task C (Div1), E (div2) I came to the conclusion that the author’s solution is wrong, so I bring to you all a huge apology.

However it turned out all pretests were correct and there are only a few number of incorrect hacks (only 3). After discussing the situation with MikeMirzayanov we made ​​this decision:

  • Problem E almost do not effect on contest results for Div2 participants (there are only a few number of submits and no hacks), so the contest will be rated for Div2 participants.

  • The contest will be rated for Div1 participants, only if this problem have right and fast solution. I wasted all todays night (or morning) finding this solution. Therefore I propose to solve this problem by the community (if it’s possible). If during the day, i.e. 24 hours after publishing this post, one cannot find solution, Div1 competition will be considered unrated.

Once again I bring you my apologies for this mistake. I hope that we will be able to master this problem together. Feel free to write all your ideas in this post, even some wrong idea may hint at the right solution. We would be very grateful to everyone who will take part in solving of that problem.

Note that this problem appeared in problemset. All tests are correct and you may try to solve it.

UPD: 24 hours have passed. Unfortunately, no one has written the correct solution, or close to it. Div1 round is declared unrated. Many thanks to all those who put their efforts and tried to solve this problem.

Best regards, Gerald Agapov.

Read more »

 
 
 
 
  • Vote: I like it  
  • +50
  • Vote: I do not like it  

By Gerald2 weeks ago, In Russian

Добрый день, Codeforces!

Меня интересует, умеет ли кто-нибудь считать такую сумму  . Или такую сумму (они друг через друга выражаются)  (деление целочисленное).

Буду очень признателен любым методам подсчета быстрее чем линия (или около-линия).

Read more »

 
 
 
 
  • Vote: I like it  
  • +21
  • Vote: I do not like it  

By Gerald3 weeks ago, translation, In English

Good Day, Codeforces!

Remember, that at 17:15 the final of the Open Moscow Programming Championship By CROC will start.

As usual anyone wishing to participate in this round can compete in it out of competition. But as this competition is quite complex, it will be rated only for participants from Div.1.

Note that this competition is closely connected with onsite competition in Moscow. So the starting time can be shifted. Watch closely for changes in the schedule.

Read more »

 
 
 
 
  • Vote: I like it  
  • +43
  • Vote: I do not like it  

By Gerald6 weeks ago, translation, In English

Good day, Codeforces!

Today at 19:00 the Round 1 of the Open Moscow Programming Championship By CROC will start.

This is usual two-hour Codeforces round with hacks and decreasing values of problems. Everybody, who passed Qualification Round and registered for today’s round, has advanced to Round 1. The remain participants are allowed to participate in this Round out of competition. Round will be rated for everyone as usual. Contestants who gain a score equal to the 300-th place finisher score or greater will advance to the Round 2 (also you need to gain positive score).

You will find a few problems, roughly ordered by the increasing complexity. Score distribution is standard (500-1000-1500-2000-2500). During the Round the problems are judged only on pretests and system testing will take place after the end of the Round. The pretests do not cover all possible cases of input data, test your programs carefully!

Before the end of the round it is strictly forbidden to publish the problem statements/solutions/any thoughts and ideas about them elsewhere. It is forbidden to talk about the problems, discuss the statements and so on. Be honest and let the best men make it into Round 2. When the Round is over, you can discuss the problems and solutions.

It seems that this Round could be a bit hard for Div2 participants. Don’t forget that rating will be calculated only for participants, who make at least one submit.

In today’s round preparation take part: Ripatti, havaliza, HamedSaleh, RAD, Gerald, MikeMirzayanov, Delinur. A huge thank you to all of them for their work!

Good round to everybody!

Read more »

 
 
 
 
  • Vote: I like it  
  • +181
  • Vote: I do not like it  

By Gerald3 months ago, translation, In English

152A - Marks

In this problem you should do exactly what is written in the statement. Here is rough code of solution:

for (int i = 0; i < n; ++i){   
    bool wasBest = false;
    for(int j = 0; j < m; ++j){
        bool isBest = true;
        for(int k = 0; k < n; ++k)
            if(a[k][j] > a[i][j])
                isBest = false;
        if(isBest)        
            wasBest = true;
    }
    if(wasBest)
        ans++;
}      

152B - Steps

Let’s find a formula for the position (x, y) and vector (dx, dy), how many steps to stop the boy can do. You should use “almost” binary search, for example, see the code written by RAD.

for (long long cof = 1100000000; cof; cof /= 2)
    while (onField(xc + cof * dx, yc + cof * dy)) {
        xc = xc + cof * dx;
        yc = yc + cof * dy;
        ans += cof;
    }      

152C - Pocket Book

In this task, it was necessary to understand that in position 1 Vasya can get any name of a special form. More exactly, it’s the name of form s = s1 s2 s3 s4 sm, where s1 — the first letter of any of the names, s2 — the second letter of any of the names, smm-th letter of any of the names. Then the answer to the problem is the product of cnti (1 ≤ i ≤ m), where cnti is a number of different letters in the names placed in position i.

152D - Frames

It was necessary to understand if there are two borders or not.

Let’s distinguish those x — and y-coordinates, in which there are at least 3 consecutive symbols ‘#’, becouse the length of each border is no less then 3. It is clear that the coordinates of the corners of borders should be chosen only from those selected x and y. In general, the various selected x no more then 4 and various selected y no more then 4.

Except that case when the height or width of the first border is 3, and length of the second side of this border is more than 3, and one side of the second border fills a part of the inside first at least.

For example:

#######
#######
#######
#.....#
#######

The first border:

#######
#.....#
#######
.......
.......

The second border:

.......
#######
#.....#
#.....#
#######

There are 7 different y-coordinates in the example.

Carefully processed these cases separately, it is quite simple. (Let’s choose 4 y-coordinates: minimum, maximum, second minimum and second maximum).

Otherwise, if the amount selected x — and y-coordinates no more then 4, then let’s choose opposite corners of the first and second borders and verify that the selected borders — the correct borders and there are no other characters ‘#’. Checking is carried out at O(n + m) or O(1) (using partial sums).

152E - Garden

The solution of this problem is based on dynamic programming. dp[mask][v] — the value of the minimum correct concrete cover, if we consider as important elements only elements of the mask mask, and there are additionally covered the vertex v = (i, j) of the field.

There are two types of transfers.

First of all we can, as if to cut coverage on the vertex v. Then you need to go through subpattern of vertex submask, which will go to the left coverage and make an optimizing transfer. Update dp[mask][v] with the value dp[submask][v] + dp[mask ^ submask][v] - cost(v).

Second, perhaps in the vertex v in the optimal coverage mask mask, which covers the vertex v, you can not make the cut separating the set of vertices. In this case, this vertex forms something a kind of «tail». And there a vertex u exists, on which we can make the cut, with the whole shortest path from a vertex u to v belongs to the optimal coverage. Let’s precalculate the shortest paths between all pairs of cells. Now to make this transition, we should count the value of dynamics dp[mask][v] for all vertices v only on the basis of the first transition. Now you can make the second transition. For all u, dp[mask][v], update the value of dp[mask][u] + dist(v, u) - cost(u).

Let’s process separately state in which exactly one bit in the mask, and the vertex which corresponding to this bit is equal to v. In this case the answer is equal to cost(v), of course.

Thus, each solution is obtained for the O(min(3k· n· m, 2k· (n· m)2)).

Read more »

 
 
 
 
  • Vote: I like it  
  • +30
  • Vote: I do not like it  

By Gerald4 months ago, translation, In English

Good day, friends!

Today another Codeforces round for Div2 participants will be. As the last Div2 only round, this round has been prepared by a team of three people: NALPPolichka and Gerald. Traditionally, we express our gratitude for their help to Artem Rakhov (RAD) Maria Belova(Delinurand Mike Mirzayanov (MikeMirzayanov).

Score distribution: 500-1000-1500-2000-2500

Good luck and have fun of solving problems! :)

UPD: Problem analysis

Read more »

 
 
 
 
  • Vote: I like it  
  • +145
  • Vote: I do not like it  

By Gerald4 months ago, translation, In English
It was enough for solving this problem to calculate for each letter: ac - amount of occurrences of letter c in first and second strings in input, bc - amount of occurrences of letter c in third string in input. If the answer is "YES" else "NO". 

Let's bust the "level" 0 ≤ i ≤ 106, in which assumedly the stone could hit. Let’s find the minimal number of square on this level. Then we can understand, how many squares there are on this level: one or two. Then we check with one or two ifs (if on this level two squares) if the stone is in corresponding square or not. If the stone is inside then output the answer. If we didn't find any square, where the stone is, output "-1".  

Let's sort the pairs (namei, ai) by ascending of ai. If there is an index i: 0 ≤ i < n that ai > i, then answer is "-1". Otherwise the answer exists. We will iterate through the array of sorted pairs from left to right with supporting of vector of results res. Let on the current iteration ai = n - i, then we must transfer the current man in the position ai. It can be done in C++ with one line: res.insert(res.begin() + a[i], man); 

Let's generate the weighted directed graph of all ramps. The graphs' vertexes are the important points on the line Ox, there are points: 0, L, xi - pi, xi + di. The graphs' edges are the possible ramp jumps: transfer from point xi - pi to point xi + di or transfer from vertex in neighboring vertexes (neighboring means that we get the next and previous important points on the line). The weights of these edges are correspondingly pi + ti and xv + 1 - xv, xv - xv - 1. We must note that in the transfers we can't get in the negative part of Ox, and we must delete this transfers.

Then we must find and output the shortest path in this graph from vertex 0 to L. This can be done, for example, with Dijkstra's algorithm for the sparse graphs. 


In this problem we must find the minimum spanning tree, in which the half of edges are marked with letter 'S'.

There are  n - 1 edges in this tree, because of it if n is even then the answer is "-1".

Let's delete from the given graph all S-edges. And there are cnt components in obtained graph. For making this graph be connected we must add cnt - 1 edges or more, that's why if cnt - 1 > (n - 1) / 2 the answer is "-1". Then we find cnt - 1 S-edges, that we must add to the graph, so that it become connected. If cnt - 1 < (n - 1) / 2 then we will try to add in this set of edges another S-edges, so that the S-edges don't make circle. We must do all of this analogically to Kruskal's algorithm of finding a minimum spanning tree. If we could get a set of S-edges of (n - 1) / 2 elements, that there are exactly cnt - 1 edges and no S-circles, then the answer exists, Then we must add to this set (n - 1) / 2 M-edges, that forms with our set of edges the minimum spanning tree, it must be done analogically with Kruskal's algorithm.

Read more »

 
 
 
 
  • Vote: I like it  
  • +35
  • Vote: I do not like it  

By Gerald8 months ago, translation, In English
Consider three cases.
  • s = f, ans = t.
  • s < f, we must find the smallest non-negative k such, that t ≤ (s - 1) + 2(m - 1)k. ans = s - 1 + 2(m - 1)k + (f - s).
  • s > f, similarly, we must find the smallest non-negative k such, that t ≤ 2(m - 1) - (s - 1) + 2(m - 1)k. ans = 2(m - 1) - (s - 1) + 2(m - 1)k + (s - f).
We can find k in any reasonable manner, for example, by using formulas of integer division.

Suppose, that the first player made a move x ≤ a, then consider the remainder rem = x· 109%mod. Obviously, if (mod - rem)%mod ≤ b, then the second player can win. Thus, we must iterate through all relevant values of x (we don't need iterate through more than mod values) and check whether the second player to win. If there exist a losing move for second player, then won the first, else second. Since we iterate through all relevant moves of the first player, then we can easily determine his winning move (if such move exist).

Approval. If the tournament has at least one cycle, then there exist a cycle of length three.

A constructive proof. Find any cycle in the tournament by using any standard algorithm, such as depth-first search. If there is no cycle, then output -1, else choose any three consecutive vertices of the cycle v1 v2 v3 (Av1, v2 = Av2, v3 = 1). Since given graph is a tournament, then there is an edge (v3, v1), or there is an edge (v1, v3). The first of these two cases, we find immediately the cycle of length three of the vertices v1 v2 v3,  the second, we can reduce the length of the loop (erase vertex v2). 

We can reduce the length of the cycle until we find a cycle of length three.

Imagine a recursion tree our transformation F. This tree is binary. We write on the edges leading into the left subtree, zero, and on the edges, leading to the right, one. Now consider the path of some number a (hereafter, we assume that we substracted one from all numbers in the array over which we make the conversion). This path start in the root of the tree and end in some leaf, and numbers written on the edges of the path is exactly bit representation of a in order from least significant bit to the most significant bit.

Construct the recursive function which solve our problem, similar to how we carry out a query to the segment tree. Here is the prototype of this function.

solve(idx, tl, tr, l, r, u, v)

This function returns the answer to the query (l, r, u, v), if we consider only subtree with positions [tl, tr], while on the path from the root to the subtree is written bit representation of idx. If l ≤ tl ≤ tr ≤ r, then we calculate answer by formulae, else we divide our segment of positions and return sum of answers from left and right part.

As described above, the answer to the whole subtree is a formula. Here you need to use the fact that all the numbers in the subtree have the form k· 2depth + idx, where depth - depth of subtree. We must find k such, that u ≤ k· 2depth + idx ≤ v and then calculate the sum of  appropriate numbers.   

Asymptotics of this solution O(m· log(n)· (formulae - for - whole - subtree)). We can calculate formulae for whole subtree in O(logn).

In this problem, suggested a solution using heavy light decomposition. Graph, given in problem statement, is a cycle, on which are suspended trees. For each tree construct the data structure (heavy light + segment tree), which can perform change on the path from some vertex to any parent, and to maintain the amount of ones. The same structure we use for the cycle. 

Suppose, that we have no cycle, i.e. there is just a bunch of trees (forest). Then the amount of switched-on edges uniquely determines the number of connected components (each switched-on edge decrease the amount of components by one). 

Suppose, that we have only the cycle. Then, similarly, the amount of switched-on edges uniquely determines the number of connected components.

We will maintain the amount of switched-on edges in the cycle and in the all trees. So, the answer to the problem Compscicle + Compstrees - CntCicle, where Compscicle - the amount of connected components in cycle, Compstrees - the amount of connected components in all trees, CntCicle - the amount of vertexes in cycle.


Read more »

 
 
 
 
  • Vote: I like it  
  • +31
  • Vote: I do not like it  

By Gerald8 months ago, translation, In English

Hello everybody! My name is Gerald Agapov. I study at Saratov State University. Today I present you the set of, I hope interesting, problems. Good luck to all!

And also a warm thanks RAD,  MikeMirzayanov and the entire Codeforces team for the great system and this opportunity! (с) dolphinigle

UPD. 

The match has ended. Thank you for paticipating!

Top 5 Coders:
5. kelvin

Read more »

 
 
 
 
  • Vote: I like it  
  • +208
  • Vote: I do not like it  

By Gerald13 months ago, In Russian
Недавно я узнал, что есть способ перемножить два 64 битных числа по модулю третьего 64 битного числа без применения длинной арифметики. Вроде как такое перемножение можно сделать используя long double в 2 строчки кода. Прилично погуглив, я не обнаружил ничего путного на эту тему, хотя польза от такой операции весьма большая (например не прибегать к длинной арифметике в тесте миллера рабина на простоту большого 64 битного числа). Может кто-то знает как это можно сделать?  Заранее благодарен за помощь.

Read more »

 
 
 
 
  • Vote: I like it  
  • +12
  • Vote: I do not like it  

By Gerald14 months ago, In Russian
Разбираясь с тандемными повторами при решении задачи, которую обсуждали тут, я перечитал несколько трудов Гасфилда и Крочемора (не уверен что это так пишется по русски =) ) по тандемным повторам. В основном все алгоритмы, описанные там, находят все вхождения тандемных повторов в строку (примитивных, вообще всех, различных, вариаций много). И лишь только в одной статье Гасфилда отдаленно упоминается, что существует алгоритм, который отвечает для позиции i в строке, существует ли какой-нибудь (возможно минимальный) тандемный повтор начинающийся в позиции   i - L + 1 длины L. Кто-нибудь что-нибудь слышал о подобном алгоритме, статье где его можно прочитать? Или может быть кто-нибудь знает как свести одну из вышеперечисленных решенных задач к этой за приемлемое время? 
 
P.S. Гугл скромно молчит в ответ на все вопросы :(

Read more »

 
 
 
 
  • Vote: I like it  
  • +20
  • Vote: I do not like it  

By Gerald14 months ago, In Russian
На одной из тренировок школьников на NEERC в этом году, была одна интересная строковая задача. Вот её приблизительное условие:
Строка называется хорошей, если какой либо её префикс ненулевой длины и отличный от всей строки совпадает с её суффиксом. Дана строка длиной до 105 символов, нужно для каждого её циклического сдвига определить является он хорошим или нет.

Условие в оригинале и авторское решение по задаче можно найти где-то-тут. Оригинальное название задачи "Заклинание Границы".

В авторском решении, что-то весьма хитрое с z-функцией и разделяй-и-властвуй, кажется, я не очень понял. Предлагаю пообсуждать решение здесь :). 


P.S. Некто e-maxx, говорил, что, вроде бы, подобная задача была когда то в Петрозаводске на Станкевич контесте. И что у нее есть решение как z-функцией, так и суффиксным деревом. 

Read more »

 
 
 
 
  • Vote: I like it  
  • +6
  • Vote: I do not like it  

By Gerald14 months ago, In Russian
Помнится мне на разборе задач полуфинала Petr объяснял все задачи пользуясь презентацией или чем то подобным, кто нибудь знает где можно эту презентацию достать? 

Read more »

 
 
 
 
  • Vote: I like it  
  • +11
  • Vote: I do not like it  

By Gerald15 months ago, In Russian
Собственно задача состоит в следующем, есть строка зашифрованная по RLE, т.е. представленная в виде (x1)k1(x2)k2...(xn)kn, где (xi)ki означает строку из символов ki длины xi (например строку AAABBCCC можно представить в виде (3)A(2)B(3)C). Нужно отвечать на запросы Qi, вывести Prefix(Qi). (Prefix(i) - префикс функция i-го префикса строки). 

Ограничения: ki до 109, Количество блоков в RLE до 50000, запросов 105.

Предлагаю совместными усилиями "одержать" эту задачу. =)

Read more »

 
 
 
 
  • Vote: I like it  
  • +13
  • Vote: I do not like it  

By Gerald16 months ago, In Russian
    Наверное затронутая тема стара как наш с вами мир, но на кодифорсес (до сегодняшнего дня ничего подобного я не видел. 

    Итак...(барабанная дробь) всё началось с того, что я пересел на Ubuntu. И теперь вдохновленный идеями опенсорса качаю подряд весь софт, какой только непопадя, чтобы хоть как нибудь удовлетворить свои ненасытные потребности кодинга, серфинга и прочего прочего... 
    Как и полагается, очень долго и тщательно я выбирал редактор кода. И вот перепробовав целую кучу подобных редакторов, я остановил свой выбор...(и тут снова барабанная дробь) на Emacs... Не могу сказать, что emacs мне сразу понравился, честно говоря, удалял и устанавливал вновь его я где-то раза 2-3...=) В общем, я уже почитал достаточно манов, но хотелось бы услышать мнение сообщества... какие расширения, key биндинги, и прочие прелести настройки редактора используете вы? Хотелось бы услышать мнения метстных Гуру emacs о том как его надо настраивать и какие горячие сочетания клавиш использовать? В общем всё что может быть полезно начинающему emacsЕРУ пишите здесь... думаю это многим будет полезно... =)

Read more »

 
 
 
 
  • Vote: I like it  
  • +3
  • Vote: I do not like it  

By Gerald18 months ago, In Russian
Как то раз, на одном TCM контестов (или что-то в этом роде), встречалась следующая задача: Дано логическое выражение с переменными, нужно его так преобразовать, чтобы получить минимальное по длине эквивалентное ему выражение. Хотелось бы узнать как решать подобную задачу? Может кто-нибудь знает статьи или классические алгоритмы решения такой задачи?

Read more »

 
 
 
 

By Gerald20 months ago, In Russian
На одной из прошлых тренировок ИТМО я наткнулся на одну интересную задачу. В ней давалась строка и делались следующие запросы, перевернуть отрезок с L по R, найти LCP двух суффиксов i, j, длина строки 106, да и запросов тоже 105. На контесте тогда я не успел добраться до нее, заступорился на более простых задачах, а в дорешивании не смог придумать как решать. Подозрительное слово переворот так и напрашивает декартово дерево из хешей, но как его поддерживать не очень понятно =)


В общем, Хотелось бы узнать как решается эта замечательная задача =). Жду комментариев!=)

Read more »

 
 
 
 
  • Vote: I like it  
  • +4
  • Vote: I do not like it  

By Gerald20 months ago, In Russian
Задача предложена Раховым Артемом (RAD.). 
Решение:
Посмотрим на ГМТ точек куда может приземлиться ДравДэ, есть несколько случаев: 
  1. ГМТ - угол, в том случае, если проекции их на плоскость Oxy есть вектора линейно независимые. Получить этот угол достаточно просто. Вершина его будет очевидно в точке старта ДравДэ, один из образующих лучей будет сонаправлен с проекцией вектора скорости самолета, другой просто вычисляется 
    Az  + Vz * tv + Uz *  tu = 0
    Ax  + Vx * tv + Ux*  tu = Bx
    Ay  + Vy * tv + Uy *  tu = By
    где A стартовая точка, а B та точка куда ДравДэ приземлится. Подставив в качестве tv 
    например 1 можно легко вычислить t2 из первого уравнения и далее найти точку B. Это и будет точка на втором луче.
  2. ГМТ - луч или прямая, в том случае если проекции векторов скоростей линейно зависимы, луч когда ветер дует не слишком сильно =). 
Понятно, что ответ существует только в том случае, если есть пересечения многоугольника и ГМТ приземления. Так же легко понять, что минимальные времена полета получаются в критических точках, то есть в точках пересечения многоугольника и сторон угла (и с лучом), а также в  вершинах многоугольника. Найдем времена t1, t2 во всех таких точках и выберем минимальные (в смысле минимальности описанной в условии). Искать эти времена можно их естественных соображений, тогда будут возникать случаи ---> ифы ---> БАГИ. Намного удобнее выписать все соотношения в виде линейных уравнений и решить их. (там тоже возникают неприятные случаи, но в этом случае их намного меньше).

Read more »

 
 
 
 
  • Vote: I like it  
  • +3
  • Vote: I do not like it