---
# System prepended metadata

title: Chữa bài chiều 29-6-23

---

## Bquery - Editorial

Thay vì duyệt theo từng $bit$, ta có thể sử dụng các hàm tiện ích ```builtin``` như sau:

- Với truy vấn $1$: dùng ```buitin___builtin_popcount(x)```, hàm này trả về số lượng $bit$ $1$ trong $x$.
- Với truy vấn $2$: 
    - Nếu $x = 0$ in ra $-1$.
    - Ngược lại in ra ```31 - __builtin_clz(x)```.
    - Hàm ```__builtin_clz(x)``` miêu tả số $bit$ $0$ ở đầu số $x$ dưới dạng nhị phân, lưu ý là chỉ dùng cho số dạng ```int```, vậy nên ta lấy $31$ trừ đi hàm này.
- Với truy vấn $3$:
    - Nếu $x = 0$ in ra $-1$.
    - Ngược lại in ra ```__builtin_ctz(x)```. Hàm này miêu tả số $bit$ $0$ ở cuối $x$ dưới dạng nhị phân.

Những hàm tiện ích trên sẽ giúp tối ưu về mặt hệ số hơn là đi tính từng $bit$.

## AndSort - Editorial

### Subtask 1

Ta thử từng $X$ từ $0$ đến $n-1$, rồi thử dùng sắp xếp nổi bọt để kiểm tra.

Độ phức tạp $O(n^3)$.

### Subtask 2

Ta coi dãy $p$ là $p_0,p_1,p_2,...,p_{n-1}$.

Ta nhận thấy rằng, chỉ cần phải dịch chuyển những vị trí $i$ có $p_i \neq i$, như vậy kết quả chính là tập con chung của các $p_i$ này, hay bằng $p_{i0} \& p_{i1} \& p_{i2} \& ... \& p_{ix}$, với $p_{ij}$ là các phần tử thỏa mãn $p_{ij} \neq ij$.

Để tìm tập con này, đầu tiên ta khởi tạo ```res = (1 << 20) - 1```. Nghĩa là khởi tạo kết quả gồm tất cả các $bit$ từ $0->19$ đều bật. Sau đó với $p_i \neq i$, ta thực hiện ```res &= p[i]```.

Kết quả sau cùng chính là biến ```res```.

## MinOp - Editorial

### Subtask 1

Ta quay lui để duyệt tất cả các trường hợp.

Độ phức tạp: $O(2^n)$.

### Subtask 2

Giả sử $S$ là kết quả của bài toán.

Như vậy, ta sẽ luôn có $c_i | S = S$, $\forall 1 \le i \le n$.

Do $a_i,b_i < 2^9$, nên $S < 2^9$.

Vậy, ta có thể duyệt từng giá trị của $S$ từ bé đến lớn để thử, với mỗi $1 \le i \le n$ xem liệu có thể tạo ra $c_i$ sao cho $c_i | S = S$ hay không, nếu tất cả các $i$ đều có thể thì $S$ là giá trị thỏa mãn và ngừng tìm kiếm.

Độ phức tạp: $O(2^9*n*m)$.

## XorAll - Editorial

### Subtask 1

Sinh nhị phân ra toàn bộ các dãy con để tính.

### Subtask 2

Phép $xor$ có tính khử như sau : $a \oplus a = 0$.

Vậy, nếu một giá trị xuất hiện chẵn lần trong phép $xor$, tất cả sẽ bị khử về $0$.

Một phần tử sẽ xuất hiện $2^{n-1}$ lần trong tất cả các dãy con, vậy nếu $n = 1$, kết quả sẽ là $a_1$, ngược lại $n > 1$, tất cả các phần tử sẽ xuất hiện chẵn lần, vậy ta có kết quả là $0$.

## XorTree - Editorial

### Subtask 1

Ta cố đỉnh từng đỉnh $u$ và $dfs$ để tính được hết các $f(u,v)$.

Độ phức tạp: $O(n^2)$.

### Subtask 2

Ta tạm coi "gốc" của cây là $1$. Ta sẽ $dfs$ từ đỉnh $1$ và thu được $lv[u]$ là tổng $xor$ của trọng số cạnh trên đường đi từ $1$ tới $u$.

Lúc này, $f(u,v)$ sẽ bằng $lv[u] \oplus lv[v]$, với $\oplus$ là toán tử $xor$. Ta có thể chứng minh điều này như sau:

- Gọi $c$ là cha chung gần nhất của $u$ và $v$.
- Ta có:
    - $f(u,v) = (lv[u] \oplus lv[c]) \oplus (lv[v] \oplus lv[c])$
    - $f(u,v) = lv[u] \oplus lv[v] \oplus (lv[c] \oplus lv[c])$
    - $f(u,v) = lv[u] \oplus lv[v]$.

Như vậy, với mỗi $u$, ta cần đi tính giá trị của tất cả các $lv[u] \oplus lv[v]$. Tuy vậy, duyệt từng $v$ sẽ không đủ nhanh.

Thay vào đó, ta sẽ tính theo từng $bit$.

Gọi $cnt[i][j]$ $(0 \le i \le 20, 0 \le j \le 1)$ là số lượng đỉnh $u$ với $lv[u]$ có giá trị của $bit$ thứ $i$ là $j$.  

Sau khi tính được mảng $cnt$, ta duyệt từng đỉnh $u$, sau đó duyệt từng $bit$ trong $lv[u]$.

Giả sử $bit$ thứ $i$ có giá trị là $1$, ta sẽ cộng vào kết quả $2^i * cnt[i][0]$, bởi nếu $lv[u]$ $xor$ với một $lv[v]$ nào đó chứa $bit$ thứ $i$ bằng $0$, kết quả thu được sẽ có $bit$ thứ $i$ bằng $1$ và đem lại giá trị $2^i$. Ngược lại nếu $lv[v]$ có $bit$ thứ $i$ bằng $1$, kết quả thu được sẽ có $bit$ thứ $i$ bằng $0$ và không đem lại thêm giá trị nào.

Tương tự với trường hợp $bit$ thứ $i$ có giá trị $0$.

Ta có thể thấy rằng, từng $bit$ này độc lập với nhau, nên ta sẽ thu về kết quả đầy đủ.

Độ phức tạp: $O(n*log)$.

## SeqXor - Editorial 

### Subtask 1

Sinh nhị phân cả $2$ dãy để kiểm tra.

### Subtask 2

Dựa vào điều kiện:
- $max (i_1, i_2, ..., i_k, j_1, j_2, ..., j_q) - min (i_1, i_2, ..., i_k, j_1, j_2, ..., j_q) = k + q - 1$
- Ta nhận thấy rằng do $max$ và $min$ chỉ số của hai dãy này cách nhau đúng $k + q - 1$ đơn vị, nên chỉ số của hai dãy này cấu thành nên một đoạn con liên tiếp.

Lại có:
- $a_{i1} \oplus a_{i2} \oplus ... \oplus a_{ik} = a_{j1} \oplus a_{j2} \oplus ... \oplus a_{jq}$; 
- Như vậy, có thể đổi vế và cho ra tổng $xor$ của hai dãy này bằng $0$.

Vậy, ta có thể duyệt từng đoạn con $[l,r]$ liên tiếp, kiểm tra xem tổng $xor$ của chúng có bằng $0$ hay không, nếu có thì đáp án cộng vào $2^{r-l} - 1$, bởi sẽ có đúng $2^{r-l} - 1$ cách chọn đoạn $[l,r]$ ra hai tập con không rỗng.

Độ phức tạp: $O(n^2)$.
### Subtask 3

Gọi $s_i$ là $prefix$ $xor$ từ $a_1$ tới $a_i$.

Tổng $xor$ trong đoạn $[l,r]$ sẽ là $s_r \oplus s_{l-1}$.

Như vậy ta có thể cải tiến từ $subtask$ $2$ lên như sau:

- Lưu một ```map<int ,ii> mp```.
- Khi duyệt đến một $s_i$, ta cần đi tìm những $s_j$ sao cho $s_j = s_i$, để đoạn $[j+1,i]$ có tổng $xor$ bằng $0$. Các giá trị $j$ này sẽ đóng góp vào kết quả như sau:
    - $(2^{(i-j_1 - 1)}-1) + (2^{(i-j_2 - 1)}-1) + ... + (2^{(i-j_k - 1)}-1)$
    - Hay: $2^i * (\frac{1}{2^{j_1+1}} + \frac{1}{2^{j_2+1}} + ... + \frac{1}{2^{j_k+1}}) - k$ 
- Để tính được điều này, ta dùng ```map``` như sau: 
    - $key$ lưu giá trị $prefix$ $xor$.
    - $value.first = \sum inversion(2^{(j+1)})$, với $j$ thỏa mãn $s_j = key$ và $inversion(2^{(j+1)})$ là nghịch đảo module của $2^{(j+1)}$.
    - $value.second = count(j)$, hay số lượng số $j$ thỏa mãn $s_j = key$.
    - Khi duyệt đến một giá trị $s_i$, ta cộng vào kết quả:
        - $add = mp[a[i]].first*2^i - mp[a[i]].second$
    - Đồng thời ta thêm vào ```map```:
        - $m[a[i]].first += inversion(2^{(i+1)})$.
        - $m[a[i]].second += 1$.
- Độ phức tạp: $O(n*log)$.