Kapitan Cek Sparrow#12293

Kapitan Cek Sparrow (Həll təhlili)

Problem Müəllifi:

Akbar Akbar

Hazırlayan:

Hasan Saleh (MathModel)

Redaktə edən:

Hasan Saleh (MathModel)

Həll

Hər test halı üçün aşağıdakı dəyəri hesablamağımız lazımdır:

\sum_{l=a}^{b}\sum_{r=l}^{b}\big((l\oplus r)+(l\&r)\big)\cdot(r-l)\pmod{10^9+7}.

r=l olan terminlər (r-l) faktoru səbəbindən sıfır töhfə verir, buna görə də a\le l<r\le b olan bütün cütlər üzrə cəmi yenidən yaza bilərik. Əsas addım XOR-u standart identiklikdən istifadə edərək çıxarmaqdır:

l + r = (l \oplus r) + 2(l \& r) \quad\Rightarrow\quad (l\oplus r) = l + r - 2(l\&r),

beləliklə

(l\oplus r)+(l\&r) = l + r - (l\&r).

Beləliklə, cavab aşağıdakı kimi olur:

\mathsf{Cavab} = \sum_{a\le l<r\le b} (l + r - (l\&r))(r-l) = S_1 - S_2,

burada

S_1 = \sum_{a\le l<r\le b}(l+r)(r-l), \qquad S_2 = \sum_{a\le l<r\le b}(l\&r)(r-l).

Notasiyaları daha aydın etmək üçün, yenidən indeksləyirik. n = b-a+1 götürək və x_i = a+i üçün i=0,\dots,n-1 müəyyən edək. a\le l<r\le b olan hər cüt (l,r) 0\le i<j<n olan (x_i,x_j) ilə uyğun gəlir və

r - l = x_j - x_i = (a+j)-(a+i) = j-i.

Sonra

S_1 = \sum_{0\le i<j<n}(x_i+x_j)(j-i), \qquad S_2 = \sum_{0\le i<j<n}(x_i\&x_j)(j-i).

S_1 üçün, bütün cütlər üzrə cəmləmək əvəzinə, hər bir indeks -nın töhfəsinə ayrıca baxırıq. x_k elementi sağ ucu cütlərində i=0,\dots,k-1 ilə görünür və bu cütlərin toplam məsafəsi

\sum_{i=0}^{k-1}(k-i) = 1+2+\dots+k = \frac{k(k+1)}{2}.

Eyni zamanda, o, sol ucu (k,j) cütlərində j=k+1,\dots,n-1 ilə görünür, bu da

\sum_{j=k+1}^{n-1}(j-k) = 1+2+\dots+(n-k-1) = \frac{(n-k-1)(n-k)}{2}.

Beləliklə, indeks üçün toplam məsafə çəkisi

W_k = \frac{k(k+1)}{2} + \frac{(n-k-1)(n-k)}{2},

və

S_1 = \sum_{k=0}^{n-1} x_k W_k = \sum_{k=0}^{n-1}(a+k)W_k.

Bu, üzrə bir döngü ilə, hər şeyi 10^9+7 modulunda edərək həyata keçirilir.

S_2 üçün, bitləri idarə edirik. Yazmaq olar

x_i\&x_j = \sum_{b=0}^{30} \left( (1\ll b)\ \text{əgər bit }b\text{ hər iki }x_i,x_j\text{ üçün təyin olunubsa} \right),

beləliklə

S_2 = \sum_{b=0}^{30} (1\ll b)\cdot T_b,

burada

T_b = \sum_{\substack{0\le i<j<n \\ \text{bit }b\text{ hər iki }x_i,x_j\text{ üçün təyin olunub}}} (j-i).

Bəzi bit -ni düzəldin. Yalnız bu bitin təyin olunduğu indekslərə baxın. Bu indekslərin artan sırası p_0,p_1,\dots,p_{m-1} olsun. Onda

T_b = \sum_{0\le u<v<m}(p_v-p_u).

Bunu bir keçid ilə hesablaya bilərik, cütləri açıq şəkildə saxlamadan. p_v-ni işlədərkən, onun bütün əvvəlki indekslərlə töhfəsi

\sum_{u=0}^{v-1}(p_v-p_u) = v\cdot p_v - \sum_{u=0}^{v-1}p_u.

Beləliklə, hər bit üçün saxlayırıq:

  • \text{cnt}_b = o bitin təyin olunduğu indekslərin sayı (bu -dir),

  • \text{sumIdx}_b = bu indekslərin cəmi,

  • T_b = bu bit üçün toplanmış dəyər.

İndeks -də olarkən, x = a + i olsun. -nin -ci bitinin olduğu hər bit üçün, biz yeniləyirik

T_j \mathrel{+}= \text{cnt}_j\cdot i - \text{sumIdx}_j, \qquad \text{cnt}_j \mathrel{+}= 1, \qquad \text{sumIdx}_j \mathrel{+}= i.

Sonda, hər bit üçün T_b məlumdur və

S_2 = \sum_{b=0}^{30} (T_b \bmod \text{MOD})\cdot((1\ll b)\bmod \text{MOD})\bmod \text{MOD},

burada \text{MOD}=10^9+7. Son cavab

\mathsf{Cavab} = (S_1 - S_2)\bmod \text{MOD}.

Komplekslik \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)