Автор проблеми: | Акбар Акбар |
Підготовлено: | Хасан Салех (MathModel) |
Редаговано: | Хасан Салех (MathModel) |
Розв'язок
Нам потрібно обчислити, для кожного тестового випадку, значення
Члени з r=l не вносять внесок, оскільки є множник (r-l), тому ми можемо переписати суму для всіх пар з a\le l<r\le b. Ключовим кроком є видалення XOR, використовуючи стандартну ідентичність
тому
Отже, відповідь стає
де
Щоб зробити нотацію чистішою, ми переіндексуємо. Нехай n = b-a+1 і визначимо x_i = a+i для i=0,\dots,n-1. Будь-яка пара (l,r) з a\le l<r\le b відповідає (x_i,x_j) з 0\le i<j<n, і
Тоді
Для S_1, замість того, щоб підсумовувати всі пари, ми розглядаємо внесок кожного індексу окремо. Елемент x_k з'являється в парах як правий кінець з i=0,\dots,k-1, і загальна відстань від них становить
Він також з'являється як лівий кінець (k,j) з j=k+1,\dots,n-1, що дає
Отже, загальна вага відстані для індексу становить
і
Це просто один цикл по , виконуючи все за модулем 10^9+7.
Для S_2 ми обробляємо біти. Ми можемо записати
тому
де
Фіксуємо деякий біт . Розглянемо лише індекси, де цей біт встановлений. Нехай їх індекси в зростаючому порядку p_0,p_1,\dots,p_{m-1}. Тоді
Ми можемо обчислити це за один прохід, не зберігаючи пари. Коли ми обробляємо p_v, його внесок з усіма попередніми індексами становить
Отже, ми підтримуємо для кожного біта :
\text{cnt}_b = кількість індексів, які були побачені з цим бітом, встановленим (це ),
\text{sumIdx}_b = сума цих індексів,
T_b = накопичене значення для цього біта.
Коли ми знаходимося на індексі , нехай x = a + i. Для кожного біта , для якого -й біт дорівнює , ми оновлюємо
В кінці, T_b відомий для кожного біта, і
з \text{MOD}=10^9+7. Остаточна відповідь
Складність \mathcal{O}(n + n\cdot\log n)
MOD=10**9+7
for _ in range(int(input())):
a,b=map(int, input().split())
n=b-a+1
s1=0
for i in range(n):
l=i*(i+1)//2
r=(n-i-1)*(n-i)//2
w=l+r
s1=(s1+(a+i)%MOD*(w%MOD))%MOD
c=[0]*31
si=[0]*31
t=[0]*31
for i in range(n):
x=a+i
for j in range(31):
if(x>>j&1):
t[j]+=c[j]*i-si[j]
c[j]+=1
si[j]+=i
s2=0
for j in range(31):
s2=(s2+(t[j]%MOD)*((1<<j)%MOD))%MOD
print((s1-s2)%MOD)