1. 程式人生 > >Codeforces617 E . XOR and Favorite Number(莫隊演算法)

Codeforces617 E . XOR and Favorite Number(莫隊演算法)

XOR and Favorite Number

time limit per test: 4 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output

Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1, …, aj is equal to k.

Input

The first line of the input contains integers n, m and k (1 ≤ n, m ≤ 100 000, 0 ≤ k ≤ 1 000 000) — the length of the array, the number of queries and Bob’s favorite number respectively.

The second line contains n integers ai (0 ≤ ai ≤ 1 000 000) — Bob’s array.

Then m lines follow. The i-th line contains integers li and ri (1 ≤ li ≤ ri ≤ n) — the parameters of the i-th query.

Output

Print m lines, answer the queries in the order they appear in the input.

Sample test(s)

Input

6 2 3
1 2 1 1 0 3
1 6
3 5

Output

7
0

Input

5 3 1
1 1 1 1 1
1 5
2 4
1 3

Output

9
4
4

Note

In the first sample the suitable pairs of i and j for the first query are: (1, 2), (1, 4), (1, 5), (2, 3), (3, 6), (5, 6), (6, 6). Not a single of these pairs is suitable for the second query.

In the second sample xor equals 1 for all subarrays of an odd length.

題意:有n個數和m次詢問,每一詢問會有一個L和R,表示所詢問的區間,問在這個區間中有多少個連續的子區間的亦或和為k

思路:本題只有詢問沒有修改,所以比較適合離線處理,而莫隊演算法是離線處理一類區間不修改查詢類問題的演算法。就是如果你知道了[L,R]的答案。你可以在O(1)的時間下得到[L,R-1]和[L,R+1]和[L-1,R]和[L+1,R]的答案的話。就可以使用莫隊演算法。,第一次接觸莫隊演算法感覺是一種很優雅的暴力,莫隊演算法是莫濤發明的。先對序列分塊。然後對於所有詢問按照L所在塊的大小排序。如果一樣再按照R排序。然後按照排序後的順序計算。為什麼這樣計算就可以降低複雜度呢。
一、i與i+1在同一塊內,r單調遞增,所以r是O(n)的。由於有n^0.5塊,所以這一部分時間複雜度是n^1.5。
二、i與i+1跨越一塊,r最多變化n,由於有n^0.5塊,所以這一部分時間複雜度是n^1.5
三、i與i+1在同一塊內時變化不超過n^0.5,跨越一塊也不會超過2*n^0.5,不妨看作是n^0.5。由於有n個數,所以時間複雜度是n^1.5於是就變成了O(n^1.5)了。
對於這道題,假設我們現在有一個字首異或和陣列sum[],現在我們要求區間[L,R]的異或的值,用sum陣列表示就是sum[L-1]^sum[R]==K,或者說是K^sum[R]==sum[L-1]

詳細見程式碼

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <algorithm>
#define LL long long

using namespace std;

const int Max = 1100000;

const int MAXM = 1<<22;

typedef struct node
{
    int L ,R;

    int Id;
}Point ;

Point a[Max];

LL sum[Max];

LL ans[Max];

int n,m;

LL k;

int L,R;

LL cnt[MAXM],ant;

bool cmp(Point b,Point c)//將區間分塊排序
{
    if(b.L/400==c.L/400)
    {
        return b.R<c.R;
    }
    else
    {
        return b.L<c.L;
    }
}


void Dec(LL s) //將多算的數目去除
{
    --cnt[s];

    ant-=cnt[s^k];
}

void Inc(LL s)//將沒有遍歷的點對應的數目加上
{
    ant += cnt[s^k];

    cnt[s]++;
}

int main()
{
    scanf("%d %d %lld",&n,&m,&k);

    LL data;

    for(int i=1;i<=n;i++) //
    {
        scanf("%lld",&sum[i]);

        sum[i]^=sum[i-1];

    }

    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&a[i].L,&a[i].R);
        a[i].Id = i;
        a[i].L--;// 在這裡提前處理
    }
    sort(a+1,a+m+1,cmp);

    L=0,R=0,cnt[0]=1,ant=0;

    for(int i=1;i<=m;i++)
    {
        while(R<a[i].R)
        {
            Inc(sum[++R]);
        }

        while(R>a[i].R)
        {
            Dec(sum[R--]);
        }
        while(L<a[i].L)
        {
            Dec(sum[L++]);
        }
        while(L>a[i].L)
        {
            Inc(sum[--L]);
        }

        ans[a[i].Id]=ant;
    }
    for(int i=1;i<=m;i++)
    {
        printf("%lld\n",ans[i]);
    }
    return 0;
}

相關推薦

Codeforces617 E . XOR and Favorite Number(演算法)

XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: standard

CodeForces - 617E XOR and Favorite Number (+前綴異或和)

cti 暴力 連續 air codeforce oid 前綴 truct iostream 題意:給你一個長為n的序列,在給你一個m次詢問,每次詢問區間內能有多少個連續子序列的異或和為k 題解:還是莫隊啊,暴力搞事情啊。假設a^b=k, 那麽我們每次莫隊add的時候只要an

codeforces 617 E. XOR and Favorite Number算法)

truct .com src sort while 開始 算法 printf turn 題目鏈接:http://codeforces.com/problemset/problem/617/E 題目:   給你a1 a2 a3 ··· an 個數,m次詢問:在[L, R] 裏

CodeFroce Round 340 div2 E XOR and Favorite Number算法】

logs pairs num ble ber col nod 操作 app 題面: Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query

Codeforces Round #340 (Div. 2) E. XOR and Favorite Number算法 + 異或和前綴和的巧妙】

lag ans integer ons lap stand 推出 open closed 任意門:http://codeforces.com/problemset/problem/617/E E. XOR and Favorite Number time limit p

CodeForces E. XOR and Favorite Number(Div.2)

題解 一個莫隊的基礎題,題目要求[L,R]裡面有多少對子區間異或值為k,記錄一下字首異或和arr,因為xx=0,現在我們要求區間[L,R]的異或和值,用arr陣列表示就是arr[L-1]arr[R]=k,或者說arr[R]^k=arr[L-1] import

【Codeforces Round 340 (Div 2)E】【演算法 真實區間思想】XOR and Favorite Number m組區間詢問 問區間中多少連續段異或值為k

E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input standard input output

算法)CodeForces - 617E XOR and Favorite Number

iostream col con str stream cto logs 數列 ron 題意: 長度為n的數列,m次詢問,還有一個k。每次詢問詢問詢問從數列的L到R內有多少個連續子序列異或起來等於k。 分析: 因為事先知道這題可以用莫隊寫,就正好用這題練習莫隊。

Codeforces 617E XOR and Favorite Number

input first statement 每次 while 理解 ast tty body 題目鏈接:http://codeforces.com/problemset/problem/617/E 題目: Bob has a favorite n

【codeforces 617E XOR and Favorite Number】【分塊】【多次查詢求區間[l,r]中區間異或等於k的子區間個數】

【連結】 【題意】 給定一個數組,多次查詢,問區間l,r中有多少個子區間滿足區間異或為k 【思路】 查詢很大,意味著每次回答的時間複雜度不能太大。對於本題,我們可以維護一個字首異或,sum[i],區間[a,b]異或為k等價於sum[a-1]^sum[b]=k,假如

XOR and Favorite Number CodeForces - 617E --異或字首和

 CodeForces - 617E  給n個數, m個詢問, 每次詢問問你[l, r]區間內有多少對(i, j), 使得a[i]^a[i+1]^......^a[j]結果為k。(注意 i ! =  j)維護一個字首異或值就可以了。要注意的是 區間[l, r], 我們需要將pr

XOR and Favorite Number CodeForces - 617E --異或前綴和

per col pac scan pre turn spa del %d CodeForces - 617E 給n個數, m個詢問, 每次詢問問你[l, r]區間內有多少對(i, j), 使得a[i]^a[i+1]^......^a[j]結果為k。(註意 i ! =

演算法 Codeforces617E XOR and Favorite Number

題意:給n個數和一個k,有很多次查詢,每次查詢有l,r,求[l,r]有多少個子區間的xor之和等於k 思路:很明顯是個裸莫隊演算法(原來在國外也爛大街 有幾個要注意的地方,就是對於左端點操作的時候,實際上是操作L-1,以及vis和sum的更新順序 還有就是記錄數量的時候,

CodeForces - 617E XOR and Favorite Number+前綴和)

con main 情況 前綴和 equal tex mda urn ctime Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query i

【CodeForces617E】XOR and Favorite Number

題目連結: 題解: 莫隊演算法 考慮如何進行轉移,對於異或運算有一個性質,即a^a=0 那麼我們就可以維護一個異或的字首和a[i],可以O(1)查詢L到R的區間異或和,即a[R]^a[L−1] 用flag陣列統計L到R區間中某個值的個數,那麼每次d

[CF617E]XOR and Favorite Number

617E:XOR and Favorite Number 題意簡述 給出一個n個元素的數列a,q個詢問,每個詢問查詢有多少l≤i≤j≤r,ai⊗ai+1...aj−1⊗aj=k 資料範圍

「知識學習&日常訓練」演算法(一)(Codeforce Round #340 Div.2 E

題意 已知一個長度為\(n\)的整數數列\(a[1],a[2],…,a[n]\),給定查詢引數\(l,r\),問\([l,r]\)內,有多少連續子段滿足異或和等於\(k\)。 也就是說,對於所有的\(x,y (l\le x\le y\le r)\),能夠滿足\(a[x]\oplus a[x+1]\oplus

演算法 優雅的暴力 (Codeforences # 340 E div2)

【解題前學習到的東西---莫隊演算法】            在我現在粗淺的認知看來,莫隊演算法的主要精髓就是面對已知的詢問資訊,將這些詢問進行順序調整然後離線操作。            例如對於多個詢問[l1,r1],[l2,r2]……[li,ri],如果已知了[l

關於分塊演算法and演算法

先說分塊演算法(這是一個線上的演算法) 我們將長度為n的序列分為sqrt(n)個小塊 對於每個詢問區間[l, r], 有些塊是完全包含其中的,有些塊是部分包含的 對於完全包含其中的塊

Newcoder 39 F.重排的迴文串(演算法+位運算)

Description 給一個長為 n n n 的只含小寫字母的字串 每次查詢一個區間$ [l