zoukankan      html  css  js  c++  java
  • CF 617E【莫队求区间异或和】

    E. 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 nm 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.

    Examples
    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个询问和常数K
    多个询问L,R,求有多少对(i,j)满足L<=i<=j<=R且i到j异或和为K

    分析:
    这题妙啊
    总结经验
    1.看到多个询问L,R的要考虑到莫队
    2.看到区间异或和的要想到转化成前缀和,变成Si^Sj==K的简化问题
    3.看到异或的时候要考虑到,经过异或权值范围会比数据中给得大(异或一下权值就不是原范围了)
    3.看到权值不是很大的情况下,考虑能不能用桶
    4.看到求多少对的问题要注意开long long
    5.区间异或和转换成前缀和后,实际取值中i为L-1<=i<R,要特判加上L-1的贡献(就类似于树上莫队特判lca)

                                          转载自acha

    2017-04-06

    Select Code
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=4e5+5;
    typedef long long ll;
    struct block{int l,r,id;}Q[N];
    int n,m,K,bsize,a[N];
    ll nowans,ans[N],cnt[N*10];
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    bool operator <(const block &a,const block &b){
    	return a.l/bsize!=b.l/bsize?a.l/bsize<b.l/bsize:a.r<b.r;
    }
    inline void ins(int x){
    	nowans+=cnt[K^x];
    	cnt[x]++;
    }
    inline void del(int x){
    	cnt[x]--;
    	nowans-=cnt[K^x];
    }
    int main(){
    	n=read();m=read();K=read();bsize=sqrt(n+0.5);
    	for(int i=1;i<=n;i++) a[i]=read(),a[i]^=a[i-1];
    	for(int i=1;i<=m;i++) Q[i].l=read(),Q[i].r=read(),Q[i].id=i;
    	sort(Q+1,Q+m+1);
    	int l=1,r=0;
    	for(int i=1;i<=m;i++){
    		while(l>Q[i].l) ins(a[--l]);
    		while(l<Q[i].l) del(a[l++]);
    		while(r<Q[i].r) ins(a[++r]);
    		while(r>Q[i].r) del(a[r--]);
    		ans[Q[i].id]=nowans+cnt[K^a[l-1]];
    	}
    	for(int i=1;i<=m;i++) printf("%lld
    ",ans[i]);
    	return 0;
    }
     
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define EF if(ch==EOF) return EOF;
    #define EX if(ch==EOF) return x*f;
    using namespace std;
    const int N=4e5+5;
    struct node{int l,r,id;}q[N];
    int n,m,k,bsize,a[N];
    long long nowans,ans[N],cnt[N*10];
    inline int read(){
        int x=0,f=1;char ch=getchar();EF
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();EF}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();EX}
        return x*f;
    }
    inline bool cmp(const node &a,const node &b){
        return a.l/bsize!=b.l/bsize?a.l/bsize<b.l/bsize:a.r<b.r;
    }
    inline void ins(int x){
        nowans+=cnt[k^x];
        cnt[x]++;
    }
    inline void del(int x){
        cnt[x]--;
        nowans-=cnt[k^x];
    }
    int main(){
        n=read();m=read();k=read();
        for(int i=1;i<=n;i++) a[i]=read(),a[i]^=a[i-1];
        for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
        bsize=sqrt(n);
        sort(q+1,q+m+1,cmp);
        int l=q[1].l,r=q[1].r;
        for(int i=l;i<=r;i++) ins(a[i]);
        ans[q[1].id]=nowans+cnt[k^a[l-1]];
        for(int i=2;i<=m;i++){
            while(q[i].l<l) ins(a[--l]);
            while(q[i].r>r) ins(a[++r]);
            while(q[i].l>l) del(a[l++]);
            while(q[i].r<r) del(a[r--]);
            ans[q[i].id]=nowans+cnt[k^a[l-1]];
        }
        for(int i=1;i<=m;i++) printf("%I64d
    ",ans[i]);
        return 0;
    }

    referance:

    http://codeforces.com/blog/entry/22971(官方解题报告)

    http://blog.csdn.net/qq978874169/article/details/51241737(莫队算法入门)

  • 相关阅读:
    第三百九十一、二、三、四、五、六、七天 how can I 坚持
    第三百九十天 how can I 坚持
    第三百八十九天 how can I 坚持
    POJ 1745:Divisibility 枚举某一状态的DP
    POJ 1502:MPI Maelstrom Dijkstra模板题
    POJ 1160:Post Office 邮局经典DP
    POJ 1062:昂贵的聘礼
    POJ 1125:Stockbroker Grapevine
    POJ 1236:Network of Schools
    POJ 2186:Popular Cows Tarjan模板题
  • 原文地址:https://www.cnblogs.com/shenben/p/6513003.html
Copyright © 2011-2022 走看看