Блог пользователя maxkvant

Автор maxkvant, 8 лет назад, По-русски

615A - Лампочки (Автор: TheWishmaster)

Заведем для каждой лампочки счетчик – сколько кнопок ее выключает. Если для какой-то лампочки счетчик равен 0, то ответ нет, иначе да.

Код: 15260902

615B - Длиннохвостый еж (Автор: TheWishmaster)

Посчитаем dp[i] – максимальная длина хвоста, заканчивающегося в i-ой вершине. Обновлять его просто – пройдем по всем ребрам из вершины и попытаемся увеличить текущее значение в концах ребер. Для ответа пройдемся по всем вершинам и выберем лучшую.

Код: 15260851

615C - Беговой трек (Автор: maxkvant)

Заметим, что если мы можем мы можем получить подстроку t[i, j] используя k полотен, то мы можем получить и подстроку t[i + 1, j] не более чем из k полотен. Поэтому нам выгодно каждый раз брать как можно более длинную подстроку.

Пусть n = |s|, m = |t|. На каждом этапе будем за искать эту самую длинную подстроку (lj – ее длина) в s и s_reversed, которую можем приписать к ответу.

Это можно делать несколькими способами:

  • Посчитаем lcp[i][j] — наибольший общий префикс t[i, m] и s[j, n], lcprev[i][j] — t[i, m] и s[j, 1]. Найти нужную подстроку означает найти max(max(lcp[i][1], lcp[i][2], ..., lcp[i][n]), max(lcprev[i][1], lcprev[i][2], ..., lcprev[i][n])).

Подсчёт lcp:

for (int i = m; i >= 1; i--)
     for (int j = n; j >= 1; j--) 
          if (t[i] == s[j])
              lcp[i][j] = lcp[i + 1][j + 1] + 1;

Код: 15277213

  • Заведём массив endPos, где значит endPos[j] — равна ли t[i, i + cur_len - 1] и s[j - cur_len + 1, j]. Будем пересчитывать значения этого массива, добавляя по одному символу t[i],  t[i + 1],  t[i + 2].... Аналогичный массив заведём для s_reversed. Суммарно решение отработает за

Код: 15260867

Решение бором: 15260870

bonus

можете ли вы решить задачу за , ? ?

Σ — размер алфавита.

615D - Множители (Автор: maxkvant)

Обозначим d(x) — к-во делителей числа x, f(x) — произведение делителей числа. Пусть x = p1α1p2α2... pnαn, тогда d(x) = (α1 + 1)·(α2 + 1)... (αn + 1)

. Есть пар делителитей вида , , и если x — точный квадрат добавляется ещё 1 делитель : .

для простого m и a ≠ 0 верно

Можно заметь, если a и b взаимно простые, то ,

Пользуясь этими свойствами нетрудно посчитать ответ:

d = 1;
ans = 1;
for (int i = 0; i < l; i++) {
    fp = binPow(p[i], (cnt[i] + 1) * cnt[i] / 2);
    ans = binPow(ans, (cnt[i] + 1)) * binPow(fp, d) % MOD;
    d = d * (cnt[i] + 1) % (MOD - 1);
}  

Код: 15260890

bonus

Другая задача.

Дана последовательность (p1, k1),  (p2, k2), ...,  (pn, kn)
(p_i — различные простые) и q запоросов (l, r) вычислить f(plkl·pl + 1kl + 1... prkr)%MOD.

Как решать за ?

615E - Шестиугольники (Автор: TheWishmaster)

Посмотрим, как изменяется координаты при переходе из текущего 6-угольника в каждый из смежных ему(назовем это 6 типами переходов). Если мы знаем сколько переходов каждого типа мы сделали на пути, то знаем и координаты конца пути.

Разделим весь путь на кольца:

Посчитаем количество переходов через каждую из сторон шестиугольника для 1 кольца. В каждом следующем кольце будет на 1 переход каждого типа больше, чем в предыдущем кольце. Длина каждого кольца = длина предыдущего + 6. Это арифметическая прогрессия. С помощью формулы суммы первых членов арифметической прогрессии и бинпоиска найдем номер последнего кольца и длину всех колец до него. Осталось только перебрать 6 типов последнего сделанного перехода и посчитать ответ.

Код: 15260879

Разбор задач Codeforces Round 338 (Div. 2)
  • Проголосовать: нравится
  • +30
  • Проголосовать: не нравится

»
8 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Ссылки на код не работают. Вроде это должно помочь.

»
8 лет назад, # |
  Проголосовать: нравится +34 Проголосовать: не нравится

I didn't realize the answer is when x is not a perfect square and otherwise. I solved it by calculating the answer for each individual prime power :

Let the number be p1α1·p2α2...·pkαk. Now, consider an individual prime pi. What is it's power in the final answer? It's pi(1 + 2 + ... + αi)(α1 + 1)(α2 + 1)...(αi - 1 + 1)(αi + 1 + 1)...(αk + 1). We need to find this value for every prime divisor of the number and multiply them together.

Firstly, . Thus, we can calculate the sum in O(1). Note that in order to calculate , then it is enough to take x as its remainder when divided by 109 + 6. Indeed, it is well-known that 109 + 7 is a prime. Then, by Fermat's Little Theorem, , since pi is not divisible by 109 + 7. Thus, we need to first find the exponent of the expression modulo 109 + 6.

We can easily reduce . However, how do we calculate 1 + 1)(α2 + 1)...(αi - 1 + 1)(αi + 1 + 1)...(αk + 1)} fast? Let P = (α1 + 1)(α2 + 1)...(αi - 1 + 1)(αi + 1)(αi + 1 + 1)...(αk + 1)}. This number is independent of i, so we can calculate it (mod 109 + 6) in O(k). However, the product we want is P·(αi + 1) - 1. How do we calculate the inverse of a number modulo a number? First, we do it for when the modulus is prime. It is well-known that any number (1, 2, ..., p - 1) has a unique multiplicative inverse modulo p, for some prime p. Now, by Fermat's Little Theorem, x - 1 ≡ xp - 2 mod p, so we can find x - 1 by calculating xp - 2 (in O(logp) using exponentation by squaring). Now, sadly, 109 + 6 isn't a prime. . Miraclously, is a prime, so we can in fact compute P·(αi + 1) - 1 modulo . Now, we want the exponent modulo 109 + 6. So, we need to figure out whether the product is even or odd. If at least 2 of the ais are odd, then the product is clearly even. Similarly, if all ais are even, the product is clearly even. If exactly one ai is odd, then if we calculate the prime power for pi, the product is odd, else it's even. Now, we can now use Chinese Remainder Theorem to find P·(αi + 1) - 1 modulo 109 + 6. Combining with (1 + 2 + ... + αi) finally gives us the exponent of pi modulo 109 + 6. Now, it remains to use Exponentation by Squaring to determine the desired prime power and multiply the prime powers for all prime factors of the number.

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится +6 Проголосовать: не нравится

    Really good solution!

    As for calculating (a1 + 1)(a2 + 1)...(ai - 1 + 1)(ai + 1 + 1)...(an - 1 + 1)(an + 1) fast, I think there's a more straight forward way to do this.

    All you need is prefix and suffix multiplication of (ai + 1) ,which can be solved in O(MAX_PRIME), like what I did in my code(lmul[] for prefix multiplication, rmul[] for suffix multiplication)

    	lmul[0]=1;
    	rmul[n+1]=1;
    	for(int i=1;i<=n;i++)lmul[i]=lmul[i-1]*(cnt[i]+1)%(mod-1);
    	for(int i=n;i>=1;i--)rmul[i]=rmul[i+1]*(cnt[i]+1)%(mod-1);
    

    Now, if you want to find out (a1 + 1)(a2 + 1)...(ai - 1 + 1)(ai + 1 + 1)...(an - 1 + 1)(an + 1) ,all you need is

    lmul[i-1]*rmul[i+1]%(mod-1)
    

    My code:15262736

    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится +4 Проголосовать: не нравится

      Ah I see, I did it the hard way lol. Looks like pressure of the contest took over me.

    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Hi, why do you use MOD-1 instead of MOD?

      • »
        »
        »
        »
        8 лет назад, # ^ |
          Проголосовать: нравится +1 Проголосовать: не нравится

        Hey ariel.nowik, I suggest you read the parent comment of zscoder again because what I am going to tell is already mentioned in it.

        Fermat's little theorem tells that

        i.e., any prime raised to MOD-1 is congruent to 1 modulo MOD, since MOD is itself a prime number.

        I hope you figure rest of it out.

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Thank god, I also came with this solution but I have no idea how to handle 10^9+6. Thanks a lot, it has been bothering me for an hour.

»
8 лет назад, # |
Rev. 3   Проголосовать: нравится +6 Проголосовать: не нравится

On problem B, in this statement: 3. The numbers of points from the beginning of the tail to the end should strictly increase.

With this statement, Do you want to say that the number that identifies each vertex must strictly increase? Or that the quantity of vertices should increase?

For me its ambiguous. Sorry for the bad english and thanks for the contest i had fun.

»
8 лет назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится

Did anyone manage to get AC with hashing? I got TLE on case 16 :(

»
8 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

is there anyone? Help me why my code wrong answer(after 20th). I think if there are 2, 2, 3, 3, 3

At first, I calculated total combination using given prime. Using above example, there is 2 and the count of 2 is three. and there is 3 and the count of 3 is four. So, the total is 3 x 4 = 12

When calculating the answer, each given prime can sue the total combination with division For example, I get the total combination 12 So when calculating 2, the number of 2 is three, therefore '2' can appear 12/3 = 4.

In this process, the result is below

(2x4) x (4x4) x (3x3) x (9x3) x (27x3)

ll prime[200100]; ll total = 1; ll mod = 1e9 + 7; ll ans = 1; int n;

ll power(ll a, ll b){ ll val = 1; while (b){ if (b & 1) b--, val *= a; a *= a; b >>= 1; a %= mod; val %= mod; } return val; } int main(){ //freopen("input.txt", "r", stdin); cin >> n;

for (int i = 0; i < n; i++){
    ll p; cin >> p;
    prime[p]++; //cocunt the number of prime 'p'
}
for (int i = 0; i <= 200000; i++){
    total *= (prime[i] + 1); //calculate the whole possible combination
    total %= mod;
}
for (ll i = 1; i <= 200000; i++){
    if (prime[i] != 0){
       // a/b (% p) = a * b^(p-2) % p
        ll val = i;
        ll pw = power(prime[i] + 1, (mod - 2)); //pw is b^(p-2)
       ll comb = (total * pw) % mod;
        for (ll c = 1; c <= prime[i]; c++){
            ll next = power(val, comb); 
            ans = (ans * next) % mod;
            val *= i;
            val %= mod;
        }
    }
}
cout << ans;
return 0;

}

»
8 лет назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

I did a little more analysis on B(although the solution is almost same).

Create a directed graph with edges going from higher to lower number. Now the Graph cannot have cycles just because it will disprove the definition of the graph.

Now since the Graph is a DAG we can easily apply DP on graph to take out: f(x) — the longest chain ending at x now answer is maximum of f(x) * out_degree[x]

The acyclic states was kind of unclear to me which took me time to solve it..

»
8 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

My solution to problem C: http://codeforces.com/contest/615/submission/15266012

Let rs be string s reversed. We find the longest prefix of t that is present in s or in rs, then we remove the suffix from t and repeat until t is empty. If the size of the suffix at some point is zero, then the answer is -1. One way to find such suffix is to do a binary search and get the longest suffix that is present in either s or rs.

Time complexity: O(|s||t+s|log|t|)

  • »
    »
    8 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +3 Проголосовать: не нравится

    i made something similar, i builted two suffix arrays and then i did a binary search on the suffixs for getting the maximum substring. But i removed the prefixs from t until t is empty.

    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      I find string problems too hard to solve. Could you please recommend any online courses/tutorials ? Thanks

»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Небольшая опечатка.

»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Can anyone explain why in problem D answer is calculated as ans = binPow(ans, (cnt[i] + 1)) * binPow(fp, d) % MOD; instead of ans=ans* binPow(fp, d) % MOD;

  • »
    »
    8 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    Firstly, your way to calculate answer doesn't work on test:

    3
    2 3 5
    

    f(ab) = f(a)d(b)f(b)d(a), if a and b are co prime.

    proof:

    f(x) = xd(x) / 2

    f(ab) = (ab)d(ab) / 2 = (ab)(d(a) d(b)) / 2 =   = (ad(b) / 2)d(b)(bd(b) / 2)d(a) = f(a)d(b)f(a)d(b)

»
8 лет назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится

Зачем в задаче Е нужен бинпоиск, если мы можем найти N по ближайшему S_N < n ? Просто обратно выразить по формуле?

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится +9 Проголосовать: не нравится

    Обычно, быстрее написать бинпоиск, чем выводить формулу + не надо думать об округлении вещественных чисел.

  • »
    »
    8 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +6 Проголосовать: не нравится

    Если хочешь сдать формулой:

    1. sqrtl точнее, чем sqrt.

    2. Если лень выводить, можно использовать www.wolframalpha.com.

    15272999

»
8 лет назад, # |
Rev. 2   Проголосовать: нравится +1 Проголосовать: не нравится

Problem C: I didn't understand this line:

"Now we will make an array endPos, where endPos[i] is true when t[i, i + cur_len - 1] = s[i - cur_len + 1, i]. We will update this array, adding symbols t[i], t[i + 1], t[i + 2] and so on."

what is cur_len? How to find cur_len? "adding symbols t[i], ... so on." where are we adding what? and how to use endpos to get the final answer?

Please someone clarify it in details!

»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

В задаче 615D — Множители (d(x) / 2) % (MOD — 1) можно посчитать с помощью длинной арифметики 15302663

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Круто! Не знал, что у них подключена сборка System.Numerics. У меня не компилилось без зависимости, и я не стал посылать.

»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

In problem B what if there was a shorter path with very high number of spines so when we multiply with number of spines the final result of the shorter path is bigger than the longest path?

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    we are checking from each point the longest possible tail possible with that point as endpoint multiplied by the spines. So that case is handled there

»
8 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Problem D and E were really cool problems :) Though I messed up D in contest time and couldn't check E then :( But I solved E in one try and D just after the contest :'( It could have been a really good contest for me :(

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Could u pls explain how u calculated vertex number.. After calculating ring number.?? I get that the 6 adjacent edges of each cell progress in a similar manner..however how is that generalized to calculate the offset from the starting position of the ring in which the answer vertex lies?

    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      as the arithmetic progression is 6(1+2+3+...), so I found out for which integer x 3*x*(x+1)<=n and 3*(x+1)*(x+2)>n. then I subtracted it from n. now the rest of the moves will make a partial ring. as every ring has 6 sides and and every side has x moves now, I again divided the remaining moves by x and found out on which side the last move will be. then I just wrote 5/6 cases for each side it can be on.

»
8 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Is there anyone attempt to solve Problem C with hash? I tried this, I think the complexity is about O(n^2) after I use unordered_map in c++11. However, It still takes too much time and got TLE.

I find the longest common segment in string s in this way: calculate all n^2 segments(inverse order included) hash value and stored them in unordered_map. The key in unordered_map is hash value of some segment, the value is the segment id. My code is 15269449. Could anyone tell me why TLE happened? Thank you

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

hi in 615D — Multipliers solution

d = d * (cnt[i] + 1) % (MOD — 1); why add (MOD-1) not MOD

  • »
    »
    7 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    Reason :

    Assume d is the exponent for i, i.e. i with appear in the final product d times.

    According to Fermat's little theorem, (ab)%mod = ((ab%(mod - 1))%mod) if mod is a prime number and not the other way round.

    This if I say i will appear in the final product d times modulo M, then it is safe to assume that i will appear in the final product d%(M - 1) times modulo M.(if M is a prime)

    And in this problem, M is a prime number i.e. 109 + 7.

»
6 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

d(4) = 3 , divisors (1,2,4) d(6) = 4 , divisors (1,2,3,6) d(4*6)= 8 divisors (1,2,3,4,6,8,12,24)

d(4*6) not equal d(4)*d(6)

  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    d(4) = 3 , divisors (1,2,4) d(6) = 4 , divisors (1,2,3,6) d(4*6)= 8 divisors (1,2,3,4,6,8,12,24)

    d(4*6) not equal d(4)*d(6)

    ,,edit , i got it ,, a and b should be coprimes

»
22 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

A simpler solution with less math for D:

We need to calculate $$$n^ {\frac{d}{2}} \bmod p$$$ where $$$d$$$ is the count of divisors of $$$n$$$ (this is actually still true even if $$$d$$$ is odd).

And as we all know, if $$$n = p_1^{a_1} \times p_2^{a_2} \times \ldots \times p_k^{a_k}$$$ then $$$d = (a_1 + 1) \times (a_2 + 1) \times \ldots \ (a_k + 1)$$$.

If any of $$$a_i$$$ is odd then we can divide the first $$$a_i + 1$$$ by 2 and then calculate normally.

Else every $$$a_i$$$ is even, i.e. $$$n$$$ is a square number, and we can use this fact to remove the $$$/2$$$ from $$$d/2$$$. Let $$$n = x^2$$$, then $$$n^\frac{d}{2} \Leftrightarrow (x^2)^{\frac{d}{2}} \Leftrightarrow x^{2\times \frac{d}{2}} \Leftrightarrow x^d$$$.

My (not so clean) implementation: 161385006.

  • »
    »
    14 месяцев назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Can you plz explain why you first odd ai+1 divide by 2? how it work if we divide by 2. Thanks.

    • »
      »
      »
      14 месяцев назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится

      So we need to calculate $$$n^ {\frac{d}{2}} \bmod p$$$ where $$$d = (a_1 + 1) \times (a_2 + 1) \times \ldots \ (a_k + 1)$$$.

      The problem here is $$${\frac{d}{2}}$$$. If $$$d$$$ is odd, then it will be hard for us to calculate, but $$$d$$$ is odd only if all $$$a_i + 1$$$ is odd, which means all $$$a_i$$$ is even, then $$$n$$$ is a square number and ... (like my explanation above).

      So now, $$$d$$$ is even, and we can find some $$$a_i + 1$$$ that is even, then $$$d = (a_1 + 1) \times (a_2 + 1) \ldots \times ((a_i + 1) / 2) \ldots \times (a_k + 1)$$$.

      Hope that makes sense.