CQOI2018 異或序列

2022-04-29 22:15:12 字數 1460 閱讀 8385

已知乙個長度為n的整數數列\(a_1,a_2,...,a_n\)給定查詢引數l、r,問在\(a_l,a_,...,a_r\)​區間內,有多少子串行滿足異或和等於k。也就是說,對於所有的x,y (i ≤ x ≤ y ≤ r),能夠滿足\(a_x \bigoplus a_ \bigoplus ... \bigoplus a_y = k\)的x,y有多少組。

輸入格式:

輸入檔案第一行,為3個整數n,m,k。

第二行為空格分開的n個整數,即\(a_1,a_2,..a_n\)​。

接下來m行,每行兩個整數\(l_j,r_j\)​,表示一次查詢。

輸出格式:

輸出檔案共m行,對應每個查詢的計算結果。

輸入樣例#1:複製

4 5 1

1 2 3 1

1 41 3

2 32 4

4 4輸出樣例#1:複製42

121對於30%的資料,\(1 ≤ n, m ≤ 1000\)

對於100%的資料,\(1 ≤ n, m ≤ 10^5, 0 ≤ k, a_i ≤ 10^5,1 ≤ l_j ≤ r_j ≤ n\)

首先我們明確一點。那就是異或的性質。

及\(a_1\) ^ \(a_2\) ^ \(a_3\) ^ \(a_4\) ^ \(a_5\)...

就同等於 \(sum_5\) ^ \(sum_0\) sum表示字首和

然後我們要知道怎麼去維護異或和為k是吧。

根據a^b=c可知 ac=k,ak=c。

所以我們只需要知道乙個字首和異或k的值與當前哪些序列的值相等。然後加上那些序列的個數即可。

那麼最後讓莫隊在字首和上移動,因為當前字首和就是乙個序列對吧。

關於有人不懂子串行是怎麼實現的。

以1到5為例,依次放入字首和。

用莫隊對當前異或值進行計數。然後每放入乙個,就更新異或值和讓答案加上(異或值^k)的數量。這個過程就相當於\(sum_r\) ^ \(sum_\)

#include#include#include#include#includeusing namespace std;

int cnt[500001],val[500001],k,n,m,tmp,sum,ans[500001],ch[500001];

struct nodet[500001];

int read()

while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();

return x*w;

}bool cmp(node a,node b)

ans[t[i].id]=sum;

}for(int i=1;i<=m;i++)

printf("%d\n",ans[i]);

}int main()

CQOI2018 異或序列

哈哈哈我竟然秒切了省選題 莫隊 異或。考慮異或的性質,乙個數同時異或兩次等於沒有進行操作。那麼我們設a i 為前i個數的異或和,顯然對於乙個區間 l,now a l 1 oplus a now 就是這個區間裡面所有的數的異或和。如果 a l 1 oplus a now k 那麼ans 這等同於 a ...

CQOI 2018 異或序列

給出乙個長為 n 的數列 a 和 k 多次詢問 對於乙個區間 l i,r i 問區間內有多少個不為空的子段異或和為 k 注意到一件有趣的事,就是每次詢問的 k 相同。因為 a oplus a 0 所以子段異或問題可以看作字首異或和的異或,即 a i oplus a i 1 oplus.oplus a...

CQOI2018 交錯序列

這個題簡直有毒,o a b 3logn 的做法不卡常只比 o 2 n n 多 10 分 看到 a 和 b 簡直小的可憐,於是可以往矩陣上聯想 發現這個柿子有些特殊,好像可以二項式定理搞一搞 於是 x ay b 可以寫成 n y ay b 於是接下來就二項式定理好了 n y ay b sum a bi...