CF 617E

http://codeforces.com/problemset/problem/617/E

首先,异或和满足

ai^ai+1^...^aj=(a1^...^ai-1)^(a1^...^aj)

所以维护前缀和可以O(1)算出一段区间的异或和

对于每次询问,可以考虑莫队算法暴力移动统计每个点在区间[l,r]中的贡献

复杂度O(n√n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using std::sort;
using std::cout;
typedef long long ll;
const int N=100011;
const int M=2000011;
int blo;
struct question{
    int l,r,id;
    inline bool operator<(question A)const{
        return l/blo<A.l/blo||(l/blo==A.l/blo&&r/blo<A.r/blo);
    }
}q[N];
int n,m,k,l,r;
ll tot;
int hv[M],a[N];
ll ans[N];
inline void add(int x){tot+=1ll*hv[x^k];++hv[x];}
inline void del(int x){--hv[x];tot-=1ll*hv[x^k];}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    blo=sqrt(n);
    FOR(i,1,n){
        scanf("%d",a+i);
        a[i]^=a[i-1];
    }
    FOR(i,1,m){
        scanf("%d%d",&q[i].l,&q[i].r);
        --q[i].l;
        q[i].id=i;
    }
    sort(q+1,q+m+1);
    l=1,r=0;
    FOR(i,1,m){
        while(l<q[i].l)del(a[l++]);
        while(q[i].l<l)add(a[--l]);
        while(r<q[i].r)add(a[++r]);
        while(q[i].r<r)del(a[r--]);
        ans[q[i].id]=tot;
    }
    FOR(i,1,m)cout<<ans[i]<<'\n';
    return 0;
}

  

posted @   Stump  阅读(797)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· golang自带的死锁检测并非银弹
阅读排行:
· 一个适用于 .NET 的开源整洁架构项目模板
· AI Editor 真的被惊到了
· API 风格选对了,文档写好了,项目就成功了一半!
· 【开源】C#上位机必备高效数据转换助手
· .NET 9.0 使用 Vulkan API 编写跨平台图形应用
点击右上角即可分享
微信分享提示