码迷,mamicode.com
首页 > 编程语言 > 详细

莫队算法

时间:2019-06-14 19:48:05      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:for   minus   names   add   sort   bsp   using   space   span   

莫队算法使用分块的思想,可以解决一类离线区间询问问题。 对于序列上的区间询问问题,如果从 [l,r] 的答案能够 O(1) 扩展到 [l−1,r],[l+1,r],[l,r+1],[l,r−1] 的答案,那么可以在 O(n√?n???) 的复杂度内求出所有询问的答案。 将整个区间分为√?n个块,然后进行排序。L需要在对应的块中,而在上面的前提下R要递增。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 1e5 + 5;
int n, m, k, a[N], cnt[N * 11] = {0}, b;
LL nowAns = 0, ans[N];
struct query {
    int l, r, id;
    bool operator < (const query &rhs) const {
        if(l/b == rhs.l/b) return r > rhs.r;
        return l > rhs.l;
    }
}q[N];

void add(int p) {
    nowAns += cnt[a[p] ^ k];
    cnt[a[p]]++;
}

void del(int p) {
    cnt[a[p]]--;
    nowAns -= cnt[a[p] ^ k];
}

void solve() {
    b = (int)sqrt(n);
    sort(q, q + m);
    int l = 0, r = 0;
    cnt[0] = 1;
    for(int i = 0; i < m; i++) {
        const query &c = q[i];
        while(l > c.l) add(--l);
        while(r < c.r) add(++r);
        while(l < c.l) del(l++);
        while(r > c.r) del(r--);
        ans[c.id] = nowAns;
    }
    for(int i = 0; i < m; i++) cout << ans[i] <<endl;
}

int main() {
    cin >> n >> m >> k;
    for(int i = 1; i <= n; i++) scanf("%d", a + i), a[i] ^= a[i - 1];
    for(int i = 0; i < m; i++) scanf("%d%d", &q[i].l, &q[i].r), q[i].l--, q[i].id = i;
    solve();
}

 

莫队算法

标签:for   minus   names   add   sort   bsp   using   space   span   

原文地址:https://www.cnblogs.com/hanasaki/p/11025135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!