Реши на с++ Дана битовая строка s длины n . Ра...
Created on: December 7, 2025
Answered using GPT-5.1 Thinking by Chat01
Created on: December 7, 2025
Answered using GPT-5.1 Thinking by Chat01
Реши на с++ Дана битовая строка
s
длины
n
.
l
s
i
⋅
2
i
−
l
.
Назовём пару соседних битов
s
k
,
s
k
+
1
(
l
≤
k
<
r
) влиятельной, если после того, как значения этих битов, и только их будут поменяны местами (то есть
s
k
станет равно прежнему значению
s
k
+
1
, а
s
k
+
1
— прежнему значению
s
k
), подстрока
s
l
,
r
станет удовлетворительной.
Требуется отвечать на
q
запросов вида «для заданных
l
и
r
найдите количество влиятельных пар битов».
Формат входных данных
Первая строка входных данных содержит двоичную строку
s
(
2
≤
|
s
|
≤
10
5
), состоящую из цифр 0 и 1.
Вторая строка содержит одно целое число
q
(
1
≤
q
≤
10
5
).
Каждая из последующих
q
строк содержит по два целых числа
l
и
r
(
1
≤
l
<
r
≤
|
s
|
), задающие подстроку из очередного запроса. Позиции в исходной строке нумеруются с единицы.
Формат выходных данных
Для каждого запроса выведите одно целое число — ответ на запрос.
Система оценки
Задача состоит из четырёх подзадач.
n
. Эта подзадача оценивается в 25 баллов.
В четвёртой подзадаче дополнительных ограничений нет. Эта подзадача оценивается в 39 баллов.
Пример 1
Входные данные
0110101
5
1 7
1 2
6 7
3 5
3 6
Выходные данные
4
0
0
2
3
Ниже — решение за .
Подстрока задаёт число
Так как , то вес бита зависит только от чётности :
Поэтому нам нужны только количества единиц на позициях той же чётности, что , и другой чётности.
Эффект перестановки соседних битов и на сумму:
Итог:
Для подстроки:
Тогда:
Проблема: зависит от:
Поэтому заранее для каждой позиции пары (между и ) посчитаем, какую ∆ она даёт:
Сделаем 5 массивов по парам:
eq[k] — 1, если ,d0_1[k] — 1, если при чётном l эта пара даёт ∆ = 1,d0_2[k] — ∆ = 2 при чётном l,d1_1[k] — ∆ = 1 при нечётном l,d1_2[k] — ∆ = 2 при нечётном l.По ним считаем префиксные суммы и отвечаем на запрос за .
Значение подстроки :
Предварительно считаем префиксы:
preOdd[i] — число единиц на нечётных позициях ≤ i,preEven[i] — число единиц на чётных позициях ≤ i.Для запроса :
onesOdd = preOdd[r] - preOdd[l-1],onesEven = preEven[r] - preEven[l-1].l нечётное:
same = onesOdd,diff = onesEven;l чётное — наоборот.Тогда
cpp#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string s; if (!(cin >> s)) return 0; int n = (int)s.size(); // Сделаем 1-индексацию строки string t = " " + s; // Префиксы количества единиц на чётных и нечётных позициях vector<int> preOdd(n + 1, 0), preEven(n + 1, 0); for (int i = 1; i <= n; ++i) { preOdd[i] = preOdd[i - 1]; preEven[i] = preEven[i - 1]; if (t[i] == '1') { if (i & 1) preOdd[i]++; else preEven[i]++; } } // Массивы по парам (между i и i+1), и их префиксы vector<int> pref_eq(n + 1, 0); vector<int> pref_d0_1(n + 1, 0), pref_d0_2(n + 1, 0); vector<int> pref_d1_1(n + 1, 0), pref_d1_2(n + 1, 0); for (int i = 1; i < n; ++i) { int eq = 0, d01 = 0, d02 = 0, d11 = 0, d12 = 0; char a = t[i], b = t[i + 1]; if (a == b) { // Равные биты: ∆ = 0 всегда eq = 1; } else { int pk = i & 1; // 0 - чётный, 1 - нечётный индекс k bool is10 = (a == '1' && b == '0'); if (is10) { // Пара "10": ∆ = 1, если pk == pl, иначе 2 // pl = 0 (l чётное) if (pk == 0) d01 = 1; else d02 = 1; // pl = 1 (l нечётное) if (pk == 1) d11 = 1; else d12 = 1; } else { // Пара "01": ∆ = 2, если pk == pl, иначе 1 // pl = 0 if (pk == 0) d02 = 1; else d01 = 1; // pl = 1 if (pk == 1) d12 = 1; else d11 = 1; } } pref_eq[i] = pref_eq[i - 1] + eq; pref_d0_1[i] = pref_d0_1[i - 1] + d01; pref_d0_2[i] = pref_d0_2[i - 1] + d02; pref_d1_1[i] = pref_d1_1[i - 1] + d11; pref_d1_2[i] = pref_d1_2[i - 1] + d12; } // Для удобства продублируем последний элемент, хотя не обязательно pref_eq[n] = pref_eq[n - 1]; pref_d0_1[n] = pref_d0_1[n - 1]; pref_d0_2[n] = pref_d0_2[n - 1]; pref_d1_1[n] = pref_d1_1[n - 1]; pref_d1_2[n] = pref_d1_2[n - 1]; int q; cin >> q; while (q--) { int l, r; cin >> l >> r; // считаем S(l, r) mod 3 int onesOdd = preOdd[r] - preOdd[l - 1]; int onesEven = preEven[r] - preEven[l - 1]; int pl = l & 1; int samePar, diffPar; if (pl == 1) { samePar = onesOdd; diffPar = onesEven; } else { samePar = onesEven; diffPar = onesOdd; } int S = (samePar + 2 * diffPar) % 3; int ans = 0; if (S == 0) { // Нужны пары с ∆ = 0 — это все равные пары ans = pref_eq[r - 1] - pref_eq[l - 1]; } else { int target = (3 - S) % 3; // либо 1, либо 2 if (pl == 0) { // l чётное if (target == 1) ans = pref_d0_1[r - 1] - pref_d0_1[l - 1]; else ans = pref_d0_2[r - 1] - pref_d0_2[l - 1]; } else { // l нечётное if (target == 1) ans = pref_d1_1[r - 1] - pref_d1_1[l - 1]; else ans = pref_d1_2[r - 1] - pref_d1_2[l - 1]; } } cout << ans << '\n'; } return 0; }
Если хочешь, могу ещё дорисовать картинку/табличку с типами пар и их вкладом ∆ в зависимости от чётности l и k.