codeforces 617E 莫队入门

莫队算法就是现将上所有的点分成sqrt(n)块,然后将要查询的区间离线起来,然后进行对[L,R]变到[L - 1,R] 、或者[L + 1,R],[L,R - 1],[L,R + 1]进行O(1)的变换。

莫队算法是优雅的暴力,复杂度O(nlogn)。

题意:给出一个一个数列,然后查询在给出区间的异或值等于k的子区间的个数。

思路:先对区间进行去前缀和处理,然后区间[L,R]的异或值为sum[R] ^sum[L - 1];然后剩下来的就是进行L,R的转移了。



#include<bits/stdc++.h>
using namespace std;
#define clr(x,y) memset(x,y,sizeof x)
typedef long long ll;
const int maxn = 2e6 + 10;

int a[maxn],pos[maxn],sum[maxn];
ll num[maxn];
struct Node{int L,R,id;}q[maxn];
bool cmp(Node p1,Node p2)
{
    return pos[p1.L] == pos[p2.L] ? p1.R < p2.R : pos[p1.L] < pos[p2.L];
}
ll Ans;
int n,m,k;
void add(int x)
{
    Ans += num[sum[x]^k];
    num[sum[x]] ++;
}
void del(int x)
{
    num[sum[x]] --;
    Ans -= num[sum[x]^k];
}
ll ans[maxn];
int main()
{
    // freopen("in.txt","r",stdin);
    while( ~ scanf("%d%d%d",&n,&m,&k))
    {
        clr(num,0);sum[0] = 0;num[0] = 1;
        int ss = sqrt(n);
        for(int i = 1;i <= n;i ++)scanf("%d",&a[i]),pos[i] = i / ss,sum[i] = sum[i - 1] ^ a[i];
        for(int i = 1; i <= m;i ++)scanf("%d%d",&q[i].L,&q[i].R),q[i].id = i;
        sort(q + 1,q + m + 1,cmp);
        int l = 1,r = 0;
        Ans = 0;
        for(int i = 1;i <= m;i ++)
        {
            while(l > q[i].L)
            {
                l --;
                add(l - 1);
            }
            while(l < q[i].L)
            {
                del(l - 1);
                l ++;
            }
            while(r > q[i].R)
            {
                del(r --);
            }
            while(r < q[i].R)
            {
                add(++ r);
            }
            ans[q[i].id] = Ans;
        }
        for(int i = 1;i <= m;i ++)
        {
            printf("%lld\n",ans[i]);
        }


    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值