В этой задаче нужно было понять, что ответ это максимум из a[i] - a[i - 1] - c, для i = 2..n и не забыть, что ответ не может быть отрицательным, так как медведь может не занимать в долг бочонок меда.
В этой задаче нужно было написать решение оптимальней наивного. Для этого, например, можно перебирать первым циклом левый индекс l рассматриваемой подстроки, а вторым циклом правый индекс r рассматриваемой подстроки (l ≤ r). Если на какой-то позиции i нашлась подстрока "bear", значит все подстроки x(l, j) (i ≤ j), также содержат "bear" в качестве подстроки. Значит к ответу можно сразу прибавить |s| - j + 1 и выйти из второго цикла. Также требовалось понять, что если в строке x(l, j) не было подстроки "bear", тогда в строке x(l, j + 1) подстрока "bear" могла появиться только в последних четырех символах.
385C - Медведь и простые числа
В этой задаче нужно было решить несколько подзадач:
1) Посчитать количество вхождений каждого числа от 2 до 107 в данный в задаче набор чисел. Это можно делать быстро так. Завести массив count на 107 элементов и при считывании чисел прибавлять count[x]++.
2) Теперь научимся считать f(x).
Для начала нужно найти все простые числа до 107 и посчитать для каждого простого числа — f(x).
Как посчитать f(2)? Нужно сложить count[2],count[4],count[6],count[8],...
Как посчитать f(5)? Нужно сложить count[5],count[10],count[15],count[20],...
Как посчитать f(x)? Нужно сложить count[x],count[2·x],count[3·x],count[4·x],...
Можно заметить похожесть на алгоритм решета Эратосфена http://e-maxx.ru/algo/eratosthenes_sieve и немного видоизменить его. Также будем сохранять в массиве pre результаты этих вычислений. А именно pre[x] = f(x).
3) Теперь можно посчитать префиксные суммы на массиве pre. Это делается одним проходом слева направо, прибавляя pre[i - 1] к pre[i].
4) Зная префиксные суммы, можно отвечать за O(1) на запрос [l, r]. Это делается так pre[r] - pre[l - 1].
5) Теперь можно считывать запросы и сразу отвечать на них. При этом не стоит забывать, что правая граница в запросе может быть до 2·109, поэтому правую границу можно всегда уменьшать до 107, так как бОльших чисел в изначальном массиве все равно нет.
В этой задаче нужно было понять, что если дорога уже освещена расстоянием в dist, то следующим прожектором оптимально освещать так, чтобы левая точка освещения на оси X была равна l + dist.
Предположим, что сейчас дорога освещена с l до d. Как теперь найти самую правую точку на оси X, которая будет освещена следующим прожектором?
Для этого достаточно использовать понятие вектора и матрицы поворота.
Находим вектор (dx, dy) от прожектора до точки (d, 0). (dx, dy) = (d - x, 0 - y).
Далее этот вектор нужно повернуть на angle градусов. Для этого можно использовать матрицу поворота.
(dx, dy) = (dx·cos(angle) - dy·sin(angle), dx·sin(angle) + dy·cos(angle))
Далее этот вектор нужно домножить на k таким образом, чтобы dy стал равен единице.
Ну и теперь можно определить самую правую освещенную точку на оси X. Она равна x - y·dx.
Также не стоит забывать, что правая точка может находится где-то в бесконечности.
На этом геометрия в этой задаче закончилась.
Теперь нужно научиться быстро находить оптимальный порядок прожекторов.
Для этого стоит применить подход динамического программирования. А именно, хранить ответ для масок прожекторов.
dp[i] = оптимальный ответ для такой-то маски i. Обычно под масками подразумевают целое число, в строковой бинарной записи числа которого, стоят 0 и 1. Допустим на 2 позиции стоит 1 — это означает, что 2 прожектор уже был использован. Например, dp[6] — (6 — 1102) оптимальный ответ, если уже использованы 2 и 3 прожектора.
Идея теперь такая. Перебираем маски в динамике dp[i]. Перебираем в i маске неиспользованные прожекторы j и обновляем ответ для маски, где этот прожектор уже используется — dp[ i or 2j ] = max( dp[ i or 2j ], dp[ i ] + вычисление_самой_правой_точки()). Так как мы уже знаем как находить самую правую освещенную точку, то обновление ответа для новой маски не составит труда.
В этой задаче можно было заметить несколько вещей:
1) Заметить, что решение моделированием не проходит по времени, так как t ≤ 1018.
2) Далее можно убедиться, что задачу не решить отдельно по x и отдельно по y, так как x и y зависят друг от друга при вычислениях.
3) Также не проходит достаточно стандартный метод с поиском цикла (то есть мы попадаем в тоже самое состояние через некоторый небольшой промежуток времени). Такого может не произойти долгое время, так как ограничения на координаты большие.
Как тогда решать.
Пусть у нас есть матрица (xi, yi, dxi, dyi, ti, 1).
Умножив ее на такую матрицу long long base[6][6] = {
{2,1,1,1,0,0},
{1,2,1,1,0,0},
{1,0,1,0,0,0},
{0,1,0,1,0,0},
{0,0,1,1,1,0},
{0,0,2,2,1,1} };
мы получим значения на следующем шаге.
Откуда взялась эта матрица? Давайте распишем как меняются параметры с каждым шагом и увидим похожесть на матрицу.
x = 2·x + 1·y + 1·dx + 0·dy + 0·t + 0·1.
y = 1·x + 2·y + 0·dx + 1·dy + 0·t + 0·1.
dx = 1·x + 1·y + 1·dx + 0·dy + 1·t + 2·1.
dy = 1·x + 1·y + 0·dx + 1·dy + 1·t + 2·1.
t = 0·x + 0·y + 0·dx + 0·dy + 1·t + 1·1.
1 = 0·x + 0·y + 0·dx + 0·dy + 0·t + 1·1.
Таким образом, возведя матрицу base в степень t - 1, и потом умножив матрицу (sx, sy, dx, dy, t, 1) на base, получим значения в момент времени t.
Матрицу можно возводить в степень быстро по принципу быстрого возведения в степень по модулю. http://e-maxx.ru/algo/binary_pow
Перемножаются матрицы за куб. Итоговое количество операций 63·log(t)
Great Editorial!
There's no english editorial? :/
Все-таки матрица из одного столбца в математике называется вектором :)
I solved E (theoretically, I don't really want to implement it) by solving the system of equations:
for $t > 0$, where the values of (x, y, vx, vy)(0) are given as input parameters, and the time is 0-based.
Firstly, we want to get rid of the modulo function. We can't just compute all variables modulo N, because there's the -1, so we'll shift the coordinates to (x', y')(t), where x' = x - 1, y' = y - 1. Now the equations become
where all variables are computed modulo $N$ (we'll omit that from now on). We can compute (x, y, vx, vy)(1) from this, and further substitute for vx, vy, which gives for t > 1
Let's now define
using which we can rewrite the sum and difference of the equations above to
Once again, we define $q(t)=s(t)+t+2$ (actually, it's s(t) + t + c, and we compute the constant c by substituting and trying to get the constant term to 0), and rewrite our equations to
which can be solved explicitly (I'm lazy, so I'm just using Wolfram Alpha, read more about linear recurrent equations on Wikipedia or something):
where the parameters $A..D$ are given by the values for t ≤ 1.
This is more of a theoretical solution (since as long as we get the recurrences for d(t) and q(t), it's best to use matrix multiplication), but I just wanted to do it this way :D
i think the matrix should be that: {2,1,1,1,0,0},
{1,2,1,1,0,0},
{1,0,1,0,0,0},
{0,1,0,1,0,0},
{0,0,1,1,1,0},
{0,0,0,0,1,1} };
i tried and solved it. with this matrix.
Rev. 23????! How could this happen?! :D
Maybe for the same reason as rev.7 of my comment above — I edit my comment, click "Save", nothing happens; I wait until my internet connection is stronger, click again, and nothing happens again, etc., until I lose patience and reload the page. And look what happened: the revisions were counted, but my comment wasn't edited. Some bug of CF, maybe.
В задаче С я написал такое же решение, как тут (на GNU C++), и получил TL. Что у меня не так?
А еще используется около 512 МБ. Проблема может быть и в этом.
Я подправил немного.
Что делает эта строчка (ios_base::sync_with_stdio(0);)?
http://mirror.codeforces.com/blog/entry/10
Спасибо, теперь буду знать, как ускорить с++
Ускоряется ввод :-)
И кстати на моем компе сам алгоритм (без учета ввода/вывода) работал 3.8 секунды. Неужели на сервере настолько быстрее?
Codeforces быстрый :)
А никого не удивило то, что решение на каком-то тесте выполнялось 2012 мс?? Ведь лимит по задаче 2 секунды.
У меня похожая ситуация по этой же задаче. Мое решение прошло со временем 2121 мс.
Вот вердикт.
Nice editorial. Anyways, I had a sense that explanation of problem E does not give you an idea of how you can come up with that solution. Let me clarify that: The state can be described by following variables: x — where is the bear currently (x-coordinate); y — where is the bear currently (y-coordinate); dx — the current speed towards X axis; dy — the current speed towards Y axis; t — time passed after the start;
This information is enough to describe a state. Now let's see how the state changes: (dx)' = dx + (x+y+t), (dy)' = dy+(x+y+t), (x)' = x + (dx)' = 2x+y+dx+t, (y)'=x+2y+dy+t, (t)'= t+1.
As we see, the new state is similar to linear combination of previous state components, except for t=t+1 (1 is not in a state). It is very similar to matrix multiplication, except for we don't have 1. So we can make a matrix this way: Let's say the state is (1x6) matrix : (x, y, dx, dy, t, 1) and the matrix (M) is 100001 021110 012110 010100 001010 011111 It's easy to see why the new state is the old state matrix multiplied by M. The rest is easy, our final state is going to be the initial state matrix multiplied by the T-th power of M. Of course we're gonna use the fast exponentiation. (The naive multiplication is fine here, because the sizes are too small)
thx a lot ~ during the exam i think the raspberry will be eaten all , then the number will change from x+y-->1 a silly misunderstanding T_T
I'm sorry :) but I don't see why (x)'= x+(dx)'? Could u explain that to me?
Ah
Ah now I see it. Thank you for your explanation :)
About Problem D ,!
how u calculate calc_rightmost_lighted_point() without keeping track of the last right_most_point u get till this state !
Problem D !?!
how u can calculate calc_rightmost_lighted_point() in ur Dp without keeping the last right_most_point u can get till before this state
By the way, in problem D you can use law of sines to find the distance that is lighted with some floodlight.
In problem C , i can't understand why we add pre[i-1] to pre[i]?
If you iterate i from 2 to n-1 adding pre[i-1] to pre[i], every new pre[i] will contain sum of all pre from 1 to i
Thank you! one more question how to prove that pre[r]-pre[l-1] is answer of query?
I think it is clearer if we denote Cnt[i] = f(i) and Sum[i] = Cnt[1] + Cnt[2] + ... + Cnt[i]. Now, the answer for a query on [l, r] is Sum[r]-Sum[l-1].
Sum[r]-Sum[l-1] = (Cnt[1] + Cnt[2] + ... + Cnt[r])-(Cnt[1] + Cnt[2] + ... + Cnt[l-1]) = [(Cnt[1] + ... + Cnt[l-1]) + (Cnt[l] + Cnt[l + 1] + ... + Cnt[r])] — (Cnt[1] + ... + Cnt[l-1]) = Cnt[l] + Cnt[l + 1] + ... + Cnt[r].
-emli- ReekinAcer can u help me please. here my code for C and get WA at tc 4 !! 9731769
А какая сложность решения получается в задаче D?
O(2nn)
UPD2: да, я не прав был. Можно было бы и написать.
Nice editorial! But I suppose that a link to a solution implementing the idea outlined in the editorial for every question would help us understand them even better!
Well, you can use "Status filter"
Well, not all the accepted solutions use the idea mentioned in the editorials. It's a bit inconvenient browsing through all accepted solutions to find the one which does.
По-моему, в задаче A(Div. 2) надо найти максимум из a[i] - a[i + 1] - c для i = 1...n — 1. А написано что a[i] - a[i - 1] - c для i = 2...n
In problem C, I did made a cnt array (or say a hashmap) and did find all primes below the maximum x using Sieve of Erathosthenes, then for each prime I iterated over every number and and found f(p) and stored them in a Binary Index Tree, but that didn't help. I believe my complexity is O(n(logn)(loglogn)+m(logn+logP)+PlogP) where P(664,579~10^7) is the count of primes below maximum x so total operations are around 5e6+6e7+4e7 but it has a TLE?.This is my submission.
can anyone help me out? I have tried 385C and it gives me a runtime error on test case 4 link to my code — https://ideone.com/fork/GMagWh
I don't know if you are still looking for this :
That might be because x or y i.e the query ranges might be going out of limits. Also it may help the others who attempt it.
Edit : Also if anyone is getting TLE even after implementing same approach use:
Reduce any l or r to 10^7 if it is greater than 10^7. Try this case 1 2000 1 1424767024 1629755604
OH! thanks a lot for this test case!!!!