• [CQOI2018] 异或序列


    题目链接:戳我

    哈哈哈我竟然秒切了省选题

    莫队+异或。

    考虑异或的性质,一个数同时异或两次等于没有进行操作。那么我们设a[i]为前i个数的异或和,显然对于一个区间([l,now]),(a[l-1]oplus a[now])就是这个区间里面所有的数的异或和。如果(a[l-1]oplus a[now]=k)那么ans++,这等同于(a[l-1]=koplus a[now])

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 100010
    using namespace std;
    int n,m,k,len,ans;
    int sum[MAXN],a[MAXN],ansans[MAXN];
    struct Node{int l,r,id,t;}t[MAXN];
    inline bool cmp(struct Node x,struct Node y)
    {
        if(x.t!=y.t) return x.t<y.t;
        return x.r<y.r;
    }
    inline void add(int pos)
    {
        ans+=sum[k^a[pos]];
        sum[a[pos]]++;
    }
    inline void del(int pos)
    {
        sum[a[pos]]--;
        ans-=sum[k^a[pos]];
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]^=a[i-1];
        len=sqrt(n);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&t[i].l,&t[i].r);
            t[i].l--;
            t[i].id=i,t[i].t=(t[i].l-1)/len+1;
        }
        sort(&t[1],&t[1+m],cmp);
        int l=1,r=0;
        for(int i=1;i<=m;i++)
        {
            while(t[i].l>l) del(l++);
            while(t[i].l<l) add(--l);
            while(t[i].r<r) del(r--);
            while(t[i].r>r) add(++r);
            ansans[t[i].id]=ans;
        }
        for(int i=1;i<=m;i++)
            printf("%d
    ",ansans[i]);
        return 0;
    }
    
  • 相关阅读:
    解决IE8下VS2005,VS2008一些向导提示脚本错误问题
    12-7
    12.4
    写在十一月的尾巴
    11.28
    htm&css 颜色的浮动
    11.27
    11.26
    html基础——表格练习
    html基础——div/span
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10311261.html
Copyright © 2020-2023  润新知