<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Lelyte</title><generator>teletype.in</generator><description><![CDATA[Lelyte]]></description><image><url>https://img2.teletype.in/files/98/35/9835c921-a076-4ec4-ac97-5d8947ce0996.png</url><title>Lelyte</title><link>https://teletype.in/@lelyte</link></image><link>https://teletype.in/@lelyte?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/lelyte?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/lelyte?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sun, 19 Apr 2026 16:06:44 GMT</pubDate><lastBuildDate>Sun, 19 Apr 2026 16:06:44 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@lelyte/sqrt_opt</guid><link>https://teletype.in/@lelyte/sqrt_opt?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/sqrt_opt?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>Корневые оптимизации</title><pubDate>Fri, 16 Sep 2022 16:20:10 GMT</pubDate><category>179</category><description><![CDATA[Рассмотрим такую задачу
Мы хотим делать две операции:
  1) a[l; r] += x
  2) a[l; r] &lt; x]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(263, 48%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="NpYE">Корневая декомпозиция</h2>
    <p id="MjeK">Рассмотрим такую задачу<br />Мы хотим делать две операции:<br />  1) a[l; r] += x<br />  2) a[l; r] &lt; x</p>
    <p id="K2rZ">Решение:<br />Разобьем наш массив на K блоков (спойлер. K = √n)<br />Тогда наш отрезок запроса разобьется на неполные блоки (по краям), а так же на полные блоки</p>
    <p id="Rfoq">Для каждого неполного блока сделаем операции в тупую за O(√n)</p>
    <p id="mqcr">Теперь рассмотрим полные блок</p>
    <p id="caLH">Для операции 1:<br />Будем хранить в массиве buff[i] (где i - номер блока) - сколько мы добавили в блок i</p>
    <p id="BhsZ">Для операции 2:</p>
    <p id="08nX">Будем хранить отсортированные отрезки. Отвечать будем на запросы с помощью Бинарного поиска за O(LogN) для блока. То есть возьмем числа, для которых верно: a[i] + buff[num(i)] &lt; x</p>
  </section>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="3CeG">Алгоритм МО</h2>
    <p id="NRvq">Рассмотрим такую задачу<br />Дано много-много запросов, состоящий из границ отрезка и числа x<br />Вам нужно для каждого отрезка ответить на вопрос: Сколько чисел, лежащий в нашем отрезке равны x?</p>
    <p id="5inS">Решение:<br />Воспользуемся Алгоритмом МО</p>
    <p id="XnAf">Для начала, чтобы все работало намного быстрее, чем сейчас - сожмем числа<br />То есть:<br />Пусть есть массив [1, 5, 3, 6, 1, 6] -&gt; [1, 2, 3, 4, 1, 4]</p>
    <p id="IIrp">Воспользуемся идеей из прошлой задачи и разобьем отрезки в блоки по левой границе. Внутри блока отсортируем их по правой границе</p>
    <p id="aTpq">Дальше, внутри каждого нового блока посчитаем ответ в тупую для первого отрезка</p>
    <p id="YBVf">Дальше, для каждого блока будем двигать левые границы в тупую, а правую - только направо</p>
    <p id="1UWK">Тогда суммарно наша правая граница пройдет максимум N элементов =&gt; работает за O(N)</p>
    <p id="kQrb">Всего блоков √n =&gt; Суммарная асимптотика O(n√n) </p>
  </section>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="WGhB">Военная хитрость:</h2>
    <p id="4QfY">Нечетные блоки отсортируем по возрастанию, четные - по убыванию (это будет работать быстрее)</p>
    <p id="wLUy">лол</p>
  </section>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="i5MX">Оптимизация какого-то что?</h2>
    <p id="pxWz">жесть там какие-то тяжелые и легкие вершины, но задача изи короче мне пофиг </p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@lelyte/strings</guid><link>https://teletype.in/@lelyte/strings?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/strings?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>Z-функция, Префикс-Функция, Бор, Манакер</title><pubDate>Mon, 13 Jun 2022 08:52:27 GMT</pubDate><category>Sirius 2022</category><description><![CDATA[Z-функция - это длина максимального префикса подстроки S, который начинается в x, который одновременно является префиксом нашей строки S
s[x ... x + k] == s[0 ... k]]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(263, 48%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="UXHR">Z-функция</h3>
    <p id="lMgq">Z-функция - это длина максимального префикса подстроки S, который начинается в x, который одновременно является префиксом нашей строки S<br />s[x ... x + k] == s[0 ... k]</p>
    <p id="k6al">Код:</p>
    <pre id="FV1g">int n;
str s;
vector&lt;int&gt; z(n);
int l = 0, r = 0;
for(int i = 1; i &lt; n; i++){
    if(i &lt;= r){
        z[i] = min(z[i - l], r - i + 1);
    }
    while(z[i] + i &lt; n &amp;&amp; s[z[i]] == s[z[i] + i]){
         z[i]++;
    }
    if(z[i] + i - 1 &gt; r){
        l = i;
        r = z[i] + i - 1;
    }
}</pre>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="Nxx2">Префикс Функция</h3>
    <p id="HRyP">Префикс функцией от строки S называется такой массив p, где Pi - это длина наибольшего префикса длинны S, который также является суффиксом i-того префикса (не считая весь i-й префикс)</p>
    <p id="8tI1">Например, для строки &quot;aataataa&quot; префикс функция будет равна [0,1,0,1,2,3,4,5]</p>
    <p id="XGGS">Код:</p>
    <pre id="ohWa">int n;
str s;
vector&lt;int&gt; p(n);
for(int i = 1; i &lt; n; i++){
    int tmp = p[i - 1]
    while(s[i] != s[tmp] &amp;&amp; tmp){
        tmp = s[tmp - 1]
    }
    if(s[i] == s[tmp]){
        p[i] = tmp + 1;
    }
}</pre>
  </section>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="fRmC">Манакер</h3>
    <p id="4My6">Пусть у нас есть строка S и мы хотим в ней найти все подпалиндромы</p>
    <p id="MOxh"><a href="https://ru.algorithmica.org/cs/string-searching/manacher/" target="_blank">https://ru.algorithmica.org/cs/string-searching/manacher/</a> - тут</p>
  </section>
  <section style="background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="nmmZ">Бор</h3>
    <p id="Yekw">Бор — это структура данных для компактного хранения строк</p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@lelyte/dp_2</guid><link>https://teletype.in/@lelyte/dp_2?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/dp_2?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>ДП по подмножествам, ДП по профилю</title><pubDate>Sat, 11 Jun 2022 07:46:53 GMT</pubDate><category>Sirius 2022</category><description><![CDATA[dp[last][mask] = min длина Гамильтонова пути из S в Last, если посетить вершины mask
dp[last][mask] -&gt; dp[next][mask | (1 &lt;&lt; next)]
next не принадлежит mask
last-&gt;next есть в графе
𝒪(2^n * n^2)]]></description><content:encoded><![CDATA[
  <h2 id="XxM6" data-align="center">ДП по подмножествам</h2>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="ORiy">Вопросы, на которые вы должны сами отвечать</h3>
    <ol id="D5Ku">
      <li id="PD55">Что считаем?</li>
      <li id="mEHt">Как считаем?</li>
      <li id="WBYQ">В каком порядке считаем?</li>
      <li id="kIJ9">Какие начальные значения?</li>
      <li id="2Uj9">Где ответ?</li>
    </ol>
  </section>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="QXSx">Гамильтонов путь</h3>
    <p id="wUs5">dp[last][mask] = min длина Гамильтонова пути из S в Last, если посетить вершины mask<br />dp[last][mask] -&gt; dp[next][mask | (1 &lt;&lt; next)]<br />next не принадлежит mask<br />last-&gt;next есть в графе<br />𝒪(2^n * n^2)</p>
    <p id="IXhz">Начальные значения:<br />dp[s][1 &lt;&lt; s] = 0, остальные - INF</p>
    <p id="SM7G">Где ответ?<br />dp[i][полная маска]</p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="iBQ8">Кол-во гамильтоновых путей из вершины S</h3>
    <p id="Eydq">dp[last][mask] = кол-во Гамильтоновых путей из S в last, если посетили вершины mask<br />dp[last][mask] -&gt; dp[next][mask | (1 &lt;&lt; next)]<br />next не принадлежит mask<br />last-&gt;next есть в графе<br />dp[s][1 &lt;&lt; s] = 1<br />dp[next][mask | (1 &lt;&lt; next)] += dp[last][mask]</p>
    <p id="JUv9">Ответ?<br />SUM dp[i][(1 &lt;&lt; n) - 1]</p>
  </section>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="tnL0">Введите текст</h3>
    <p id="FBMW">Есть числа 0...2^n - 1<br />a[0], a[1], .. a[2^n - 1]<br />Для каждой mask посчитать сумму:<br />SUM a[i], где i - подмаска нашей маски</p>
    <p id="QJem">Пример:<br />mask = 6 = 100<br />a[000] + a[010] + a[100] + a[110]</p>
    <pre id="Rg9x">int n;
for(int mask = 0; mask &lt; (1 &lt;&lt; n); mask++){
    for(int submask = mask; submask &gt; 0; submask=(submask - 1)&amp;mask){
        ...
    }
}</pre>
    <p id="izr6">dp[mask][i] - сумма a[submask], где биты 0...I в mask и subtask могут различаться, а остальные совпадают </p>
    <p id="8gP8">dp[mask][0] = a[mask]<br />Если i-тый бит mask = 0, то dp[mask][i + 1] = dp[mask][i] <br />Иначе dp[mask][i + 1] = dp[mask][i] + dp[mask ^ (1 &lt;&lt; i)][i] </p>
    <pre id="pf6M">for(int i = 0; i &lt; n; i++){
    for(int mask = 0; mask &lt; (1 &lt;&lt; n); mask++){
        dp[mask][i + 1] = dp[mask][i]
        if((mask &gt;&gt; i) &amp; 1){
            dp[mask][i + 1] += dp[mask ^ (1 &lt;&lt; i)][i]
        }
    }
}</pre>
    <p id="czkT">Оптимизация: можно сделать dp - одномерным, тогда получим такой код:</p>
    <pre id="FSdy">for(int i = 0; i &lt; n; i++){
    for(int mask = 0; mask &lt; (1 &lt;&lt; n); mask++){
        if((mask &gt;&gt; i) &amp; 1){
            dp[mask] += dp[mask ^ (1 &lt;&lt; i)]
        }
    }
}</pre>
    <p id="UY27">Работает столько же, но памяти намного меньше</p>
  </section>
  <h2 id="4GQo" data-align="center">ДП по профилю</h2>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="DfJ7">пошли нафиг</h3>
    <p id="yeBY"><a href="https://wiki.algocode.ru/index.php?title=" target="_blank">https://wiki.algocode.ru/index.php?title=</a>ДП_по_профилю</p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@lelyte/fenwick_and_sparcetable</guid><link>https://teletype.in/@lelyte/fenwick_and_sparcetable?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/fenwick_and_sparcetable?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>Дерево Фенвика + Sparse Table ~ Сириус 07.06</title><pubDate>Tue, 07 Jun 2022 07:53:01 GMT</pubDate><category>Sirius 2022</category><description><![CDATA[Дерево Фенвика - структура данных, дерево на одномерном массиве, которая обладает такими свойствами, как:]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="eONt">Дерево Фенвика</h3>
    <p id="PwRO"><strong><em>Дерево Фенвика</em></strong> - структура данных, дерево на одномерном массиве, которая обладает такими свойствами, как:</p>
    <ol id="Xn3C">
      <li id="wE7l">Сумма на отрезке с L по R</li>
      <li id="Sugh">Изменение значения в какой-то позиции за O(LogN)</li>
      <li id="ekYe">Требует O(N) памяти</li>
    </ol>
    <p id="4xfX">Код:</p>
    <pre id="EkcP">ll n;
vector&lt;ll&gt; sum;

ll get_sum(ll i){ //сумма
    ll ans = 0;
    for(; i &gt;= 0; i = (i&amp;(i+1))-1){
        ans += sum[i];
    }
    return ans;
}

void update(ll i, ll x){ //обновление на точке
    for(; i &lt; n; i = (i | (i+1))){
        sum[i] += x;
    }
}

ll sum_otr(ll l, ll r){
    return get_sum(r) - get_sum(l-1);
}</pre>
    <p id="IhPn">Так же можно сделать MAX на отрезке, но это извращение, проще написать ДО</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="BkvM">Двумерное Дерево Фенвика</h3>
    <p id="lPO6">Аналогично </p>
    <p id="xMQN">Код (скорее всего с багами):</p>
    <pre id="IQXD">ll n;
vector&lt;vector&lt;ll&gt;&gt; f(MAXN, vector&lt;ll&gt;(MAXN));


ll get_sum(int i, int j){
    int r = 0;
    while(j &gt; 0){
        int k = i;
        while(k &gt; 0){
            r += f[k][j];
            k -= k &amp; -k;
        }
        j = j &amp; -j;
    }
    return r;
}


ll sum(int x1, int y1, int x2, int y2){
    return get_sum(x2, y2) - get_sum(x1, y2) - get_sum(x2, y1) + get_sum(x1, y1);
}

void add(int i, int j, int x){
    while(j &lt;= n){
        int k = i;
        while(k &lt;= n){
            f[k][j] += x;
            k += k &amp; (~k);
        }
        j += j &amp; (~j);
    }
}</pre>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="jXIY">Sparse Table</h3>
    <p id="MDZS">Sparse Table - структура данных, позволяющая находить минимум на отрезке</p>
    <pre id="uEvE">#define MAX 100010
#define LOGMAX 30

ll n;
vector &lt;ll&gt; arr;
vector &lt;vector&lt;ll&gt;&gt; Sparce(MAX, vector&lt;ll&gt;(LOGMAX));

ll task(ll l, ll r) {
    ll j = (ll) log2(r - l + 1);
    if (Sparce[l][j] &lt;= Sparce[r - (1 &lt;&lt; j) + 1][j]) {
        return Sparce[l][j];
    }
    return Sparce[r - (1 &lt;&lt; j) + 1][j];
}

...
в функции main 
for (ll i = 0; i &lt; n; i++) {
    Sparce[i][0] = arr[i];
}
for (ll j = 1; (1 &lt;&lt; j) &lt;= n; j++) {
    for (ll i = 0; (i + (1 &lt;&lt; j) - 1) &lt; n; i++) {
        if (Sparce[i][j - 1] &lt; Sparce[i + (1 &lt;&lt; (j - 1))][j - 1]) {
            Sparce[i][j] = Sparce[i][j - 1];
        } else {
            Sparce[i][j] = Sparce[i + (1 &lt;&lt; (j - 1))][j - 1];
        }
    }
}</pre>
    <p id="WcKv">Оптимизация:</p>
    <pre id="PQv7">#define MAX 100010
#define LOGMAX 30
ll n;
vector &lt;ll&gt; arr;
vector &lt;vector&lt;ll&gt;&gt; Sparce(LOGMAX, vector&lt;ll&gt;(MAX));

ll task(ll l, ll r) {
    ll j = (ll) log2(r - l);
    return min(Sparce[j][l], Sparce[j][r - (1 &lt;&lt; j)]);
}


int main() {
    for (ll i = 0; i &lt; n; i++) {
        Sparce[0][i] = arr[i];
    }
    for (ll j = 0; j &lt; LOGMAX - 1; j++) {
        for (ll i = 0; i + (2 &lt;&lt; j) &lt;= n; i++) {
            Sparce[j + 1][i] = min(Sparce[j][i], Sparce[j][i + (1 &lt;&lt; j)]);
        }
    }
}
</pre>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="9taj">Disjoint Sparse Table</h3>
    <p id="lOOr">Sparse Table не мог быть построен для тех функций от подотрезка массива, для которых каждое число подотрезка должно быть учтено ровно один раз. Disjoint Sparse Table решает эту проблему и с предподсчётом за O(nlogn) позволяет в онлайне за O(1) находить почти любые функции от подотрезка, например кол-во минимумов, или произведение по непростому модулю. ~ wiki.algocode.ru</p>
    <p id="rmKt">Основная идея: разделяй и властвуй<br /><br />TODO: написать дальше, автор конспекта закрыл ноут и пошел внимательно слушать<br /><br />Ссылки данной штуки: <a href="https://algorithmica.org/ru/sparse-table" target="_blank">https://algorithmica.org/ru/sparse-table</a>, <a href="https://wiki.algocode.ru/index.php?title=Disjoint_Sparse_Table" target="_blank">https://wiki.algocode.ru/index.php?title=Disjoint_Sparse_Table</a></p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@lelyte/number_theory</guid><link>https://teletype.in/@lelyte/number_theory?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/number_theory?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>Теория Чисел ~ Сириус 05.06</title><pubDate>Sun, 05 Jun 2022 07:27:56 GMT</pubDate><category>Sirius 2022</category><description><![CDATA[Основная теорема арифметики гласит, что каждое число раскладывается на простые множители, причем единственным образом]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="GNWx">Основная теорема арифметики</h3>
    <p id="taqV">Основная теорема арифметики гласит, что каждое число раскладывается на простые множители, причем единственным образом</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="GUdw">Факторизация за O(sqrtN)</h3>
    <p id="NuRA">Пусть у нас есть число N<br />Оно представимо в виде N = a * b. Заметим, что одно из чисел a и b &lt;= sqrt(n) (иначе a * b &gt; n) =&gt; можно перебирать делители N до его корны</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="WJWL">Решето Эратосфена за O(NLogLogN)</h3>
    <pre id="deto">//БУДЬТЕ АККУРАТНЕЙ С ПЕРЕПОЛНЕНИЕМ!!!
int n;
vector&lt;bool&gt; isPrime(n);
for(int i = 2; i &lt;= n; i++){
    isPrime[i] = true;
}
for(int i = 2; i * i &lt;= n; i++){
    if(isPrime[i]){
        for(int j = i * i; j &lt;= n; j++){
            isPrime[j] = false;
        }
    }
} </pre>
    <h3 id="pMqN">Прикол с minDiv (чтобы факторизацию делать)</h3>
    <pre id="raQK">int n;
vector&lt;int&gt; minDiv(n);
vector&lt;bool&gt; isPrime(n);
for(int i = 2; i &lt;= n; i++){
    isPrime[i] = true;
    minDiv[i] = i;
}
for(int i = 2; i * i &lt;= n; i++){
    if(isPrime[i]){
        for(int j = i * i; j &lt;= n; j++){
            isPrime[j] = false;
            minDiv[j] = min(minDiv[j], i);
        }
    }
}</pre>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="SOkD">Диофантовы уравнения</h3>
    <p id="v5l0">Уравнения вида a*x + b*y = c (a, b, c - известны)</p>
    <p id="SxQg">Прикол:<br />Если (a, b) = g, то существуют x и y такие, что a*x + b*y = g<br />(a, b) -&gt; (b, a % b) <br />b * x1 + (a % b) * y1 = g<br />(Для тех, кто не знал - a % b = a - [a / b] * b)<br />b*x1 + (a - [a / b] * b) * y1 = a * y1 + b * (x1 - [a / b] * y1)<br />Пример шапки функции:</p>
    <pre id="jo9k">int gcd(int a, int b, int &amp;x, int &amp;y){
    ...
}</pre>
    <p id="n5EQ">Заметим, что a * (x + b) + b (y - a) = a * x + b * y =&gt; x = x0 + t * b/g; <br />y = y0 - t * a/g<br /><br />Теперь решим основную задачу<br />Воспользуемся тем, что мы умеем решать для НОДа и тупо домножим коэффициенты.<br />Если c % g == 0 =&gt; решений бесконечно много<br />Если c % g != 0 =&gt; решений нет</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="RzM6">Функция Эйлера</h3>
    <p id="M6Qj">ф(n) (да, это фи) - количество взаимнопростых чисел, которые меньше n<br />ф(10) = 4</p>
    <p id="Vl4q">Заметим тупые свойства:</p>
    <ol id="kMNy">
      <li id="MWhu">ф(р) = р - 1</li>
      <li id="oPcY">ф(р^n) = p^n - p^(n - 1)</li>
    </ol>
    <p id="vCCq">Так же интересное свойство:<br />ф(a) * ф(b) = ф(a*b) для (a, b) = 1 (я не собираюсь это доказывать, так как а) это никому не нужно, б) это долго и скучно)<br /><br />Тогда достаточно просто считается ф(n) для любого n<br />ф(n) = ф(p1^L1 * p2^L2 * p3^L3 * ... ) = ф(p1^L1) * ф(p2^L2) * ... = (тупое свойство 2) = n * (p1 - 1 / p1) * ...  * (pK - 1 / pK)<br />(лучше считать через ans / p, ans *= (p - 1)<br /></p>
    <pre id="q3QH">int n;
int ans = n;
for(int i = 2; i * i &lt;= n; i++){
    if(n % i == 0){
        ans /= i;
        ans *= (i - 1);
        while(n % i == 0){
            n /= i;
        }
    }
}
if(n &gt; 1){
    ans /= n;
    ans *= (n - 1);
}</pre>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="Y9oD">Количество делителей числа</h3>
    <p id="ZN7n">Пусть у нас n = p1^L1 + p2^L2 + p3^L3 + ... + pK^LK<br />Тогда, кол-во делителей = (L1 + 1) * (L2 + 2) * (L3 + 3) * ... * (LK + 1) (очевидно)</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="KZ72">Малая Теорема Ферма</h3>
    <p id="6R1B">a^(p - 1) ≡ 1 (mod p) при (a, p) = 1</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="J6Tq">Теорема Эйлера</h3>
    <p id="KUSa">a^ф(n) ≡ 1 (mod m) при (a, m) = 1</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="1utd">Функции модульной арифметики</h3>
    <pre id="MdqI">const int MOD = 998244353;


int add(int a, int b){
    if(a + b &gt;= MOD){
        return a + b - MOD;
    }
    else{
        return a + b;
    }
}


int sub(int a, int b){
    if(a - b &lt; 0){
        return a + b - MOD;
    }
    else{
        return a - b;
    }
}
</pre>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="EP6g">Китайская теорема об остатках</h3>
    <p id="D2na">TODO (сори, я не успел записать)</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="ys88">Мем с модулями</h3>
    <p id="1ESJ">a * g ≡ b * g (mod m * g) -&gt; a ≡ b (mod m)<br />a * g ≡ b * g (mod m) -&gt; a ≡ b (mod m) при (m, g) = 1<br />a ≡ b (mod m) -&gt; a + x ≡ b + x (mod m)</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="g4cK">С из N по K</h3>
    <p id="vDdt">(n, k) = n! / (k! * (n - k)!)<br />n! = (n - 1)! * n</p>
    <p id="fvpe">надеюсь я с комментариями нигде не напутал...</p>
    <pre id="AUoX">int n;
int f[n], rf[n];
for(int i = 1; i &lt; n; i++){
    f[i] = mul(f[i - 1], i); //умножение чисел по модулю
}
rf[n - 1] = inv(f[n - 1]); //обратное число по модулю
for(int i = n - 2; i &gt;= 0; i--){
    rf[i] = mul(rf[i + 1], i + 1); //умножение чисел по модулю
}</pre>
    <p id="74UA">Мемы:<br />1/n = (n - 1)! / n!<br />N^-1 = f[N - 1] * rf[N] (mod M)</p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="46Ko">Задачка</h3>
    <p id="96fu">Надо найти все простые числа на отрезке [L, R] <br />(R-L+1 &lt; 1e7)</p>
    <pre id="IP3C">int l, r;
vector&lt;int&gt; primes; //предпосчитать
vector&lt;bool&gt; isPrime(r - l + 1, true);
for(auto &amp;i : primes){
    for(int j = i * max((l + i - 1) / i, i); j &lt;= r; j += i){
        isPrime[j - l] = false;
    }
}</pre>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="RUOh">Линейное решето Эратосфена</h3>
    <pre id="9o4E">int n;
vector&lt;int&gt; minDiv(n);
vector&lt;int&gt; primes;
iota(minDiv.begin(), minDiv.end(), 0);
for(int i = 2; i &lt; n; i++){
    if(minDiv[i] == i){
        primes.pb(i);
    }
    for(auto &amp;p : primes){
        if(p &gt; minDiv[i] || p * i &gt;= n){
            break;
        }
        minDiv[p * i] = p;
    }
}</pre>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@lelyte/scanline_sirius</guid><link>https://teletype.in/@lelyte/scanline_sirius?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/scanline_sirius?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>ScanLine ~ Сириус 04.06</title><pubDate>Sat, 04 Jun 2022 07:15:25 GMT</pubDate><category>Sirius 2022</category><description><![CDATA[Задача заключается в том, что на плоскости имеется N прямоугольников,
стороны которых параллельны осям координат. Требуется вычислить площадь объединения данных прямоугольников]]></description><content:encoded><![CDATA[
  <h3 id="dB0J">КОНСПЕКТ ЕЩЕ ПИШЕТСЯ!!!</h3>
  <h3 id="uQHD">Задача - Объединение прямоугольников</h3>
  <p id="qb3Y">Задача заключается в том, что на плоскости имеется N прямоугольников,<br />стороны которых параллельны осям координат. Требуется вычислить площадь объединения данных прямоугольников</p>
  <p id="7Tad">Тупняк - Сделаем буловую табличку, по размеру достаточную, чтобы туда поместились все наши прямоугольники. Перебираем все прямоугольники. Смотрим на очередной. Поставим в табличку единички в те клетки, которые лежат в каждом прямоугольнике. Это работает за 𝒪(𝑛𝑆), где 𝑆 — площадь таблички, так как мы 𝑛 раз проходим по табличке площади 𝑆.</p>
  <p id="aCKO">Решение за 𝒪(𝑛 log 𝑛) - Здесь мы сжимаем координаты.<br />Теперь будем хранить одну вертикальную полоску длины, равной высоте таблицы. Хранить будем, как массив интов. Делаем сканалйн по 𝑥-ам. В этой полоске поддерживаем сколько из еще открытых прямоугольников имеют данную координату по 𝑥. Открылся новый прямоугольник — ко всем нужным 𝑦 в полоске прибавили единичку. Закрылся — вычитаем единичку. Чтобы найти площадь на текущем столбце, нужно сложить площади всех точек, в которых<br />записан не ноль. Получили сложность 𝒪(𝑛2). Можно оптимизировать с помощью ДО на 𝒪(𝑛 log 𝑛)</p>
  <p id="g5Fs">Так же ссылочка на решение челика на Codeforces - <a href="https://codeforces.com/blog/entry/49797" target="_blank">https://codeforces.com/blog/entry/49797</a></p>
  <p id="Z8f2"></p>
  <h3 id="b0TS">Задача - Найти точку, накрытой наибольшим количеством прямоугольников</h3>
  <p id="CjKM">Даны n прямоугольников. Надо найти точку, которая покрыта максимальным количеством прямоугольников.</p>
  <p id="BQd6">Решение человека с Codeforces: </p>
  <p id="EdkC">Давайте возьмем y-координаты всех точек, для которых нужно определить количество прямоугольников, покрывающих их, и отметим их на вертикальной прямой, находящейся в <em>x</em> = - ∞. Давайте теперь начнем непрерывно двигать эту прямую до <em>x</em> = + ∞ и поддерживать для каждой точки количество прямоугольников, покрывающих ее.</p>
  <p id="Dlpt">Собственно, вопрос: а в какие моменты данные количества будут изменяться? Ответ: когда наша прямая &quot;входит&quot; в прямоугольник (то есть, проходит через координату <em>x</em> = <em>xleft</em> и когда она &quot;выходит&quot; из него (проходит через координату <em>x</em> = <em>xright</em>). Ну, собственно говоря, мы можем построить отсортированный массив т.н. &quot;событий&quot;, где события — это вход в прямоугольник, выход из прямоугольника и ответ на запрос количества покрывающих точку прямоугольников. Соответственно, для события входа в прямоугольник мы прибавляем единичку на отрезке [<em>ybottom</em>; <em>ytop</em>], для события выхода из прямоугольника — отнимаем единичку на соответствующем отрезке, а для события ответа на запрос — сохраняем значение количества покрывающих точку прямоугольников.</p>
  <p id="0594">PS - <a href="https://codeforces.com/blog/entry/49588" target="_blank">https://codeforces.com/blog/entry/49588</a></p>
  <p id="FBtO">Так же решение человека с форума emaxx (в конце написан код, но как говорит автор, он с багами, но баги в ДО) - <a href="https://e-maxx.ru/forum/viewtopic.php?id=368" target="_blank">https://e-maxx.ru/forum/viewtopic.php?id=368</a></p>
  <p id="HRcn"></p>
  <p id="FZXh"></p>
  <h3 id="R9JL">Задача - Сумма на прямоугольнике</h3>
  <p id="PPKJ">Решение - в конце конспект Сергея Слотина</p>
  <p id="e51k"></p>
  <p id="ZROA">Крутой конспект - <a href="https://archive.lksh.ru/2018/august/B" target="_blank">https://archive.lksh.ru/2018/august/B</a>&#x27;/notes/03.pdf</p>
  <p id="wpcM">Так же интересный конспект от Сергея Слотина - <a href="https://ru.algorithmica.org/cs/decomposition/scanline/" target="_blank">https://ru.algorithmica.org/cs/decomposition/scanline/</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@lelyte/fenwick_tree</guid><link>https://teletype.in/@lelyte/fenwick_tree?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte</link><comments>https://teletype.in/@lelyte/fenwick_tree?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=lelyte#comments</comments><dc:creator>lelyte</dc:creator><title>Тинькофф B' - Дерево Фенвика</title><pubDate>Tue, 17 May 2022 19:56:35 GMT</pubDate><category>Tinkoff Bp 2021-2022</category><tt:hashtag>lelyte</tt:hashtag><tt:hashtag>fenwick_tree</tt:hashtag><description><![CDATA[Дерево Фенвика - структура данных, дерево на одномерном массиве, которая обладает такими свойствами, как:]]></description><content:encoded><![CDATA[
  <tt-tags id="yOH7">
    <tt-tag name="lelyte">#lelyte</tt-tag>
    <tt-tag name="fenwick_tree">#fenwick_tree</tt-tag>
  </tt-tags>
  <p id="PwRO"><strong><em>Дерево Фенвика</em></strong> - структура данных, дерево на одномерном массиве, которая обладает такими свойствами, как:</p>
  <ol id="Xn3C">
    <li id="wE7l">Сумма на отрезке с L по R</li>
    <li id="Sugh">Изменение значения в какой-то позиции за O(LogN)</li>
    <li id="ekYe">Требует O(N) памяти </li>
  </ol>
  <p id="T7q8">Код взятия суммы на отрезке: (массив f - наше дерево)</p>
  <pre id="Dh18">ll get_sum(ll i){
    ll ans = 0;
    for(; i &gt;= 0; i = (i&amp;(i+1))-1){
        ans += f[i];
    }
    return ans;
}


ll sum_otr(ll l, ll r){
    return get_sum(r) - get_sum(l-1);
}</pre>
  <p id="2CzP">Обновление на точке:</p>
  <pre id="IyTQ">void update(ll i, ll x){
    for(; i &lt; n; i = (i | (i+1))){
        f[i] += x;
    }
}</pre>
  <p id="5xvc"></p>
  <p id="lJHg">Так же Дерево Фенвика можно сделать двумерным (подробности - <a href="https://e-maxx.ru/algo/fenwick_tree" target="_blank">https://e-maxx.ru/algo/fenwick_tree</a>)</p>

]]></content:encoded></item></channel></rss>