zoukankan      html  css  js  c++  java
  • 「luogu4462」[CQOI2018] 异或序列

    「luogu4462」[CQOI2018]异或序列

    一句话题意

    输入 (n) 个数,给定(k),共 (m) 组询问,输出第 (i) 组询问 (l_i) (r_i) 中有多少个连续子序列的异或和等于 (k)。数据范围均在 ([0,1e5])

    本题不强制在线,故莫队。
    记序列 (a) 的前缀异或和 (pre),用一个桶 (t_i) 记录当前查询区间内前缀异或和为 (i) 的数量。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    inline int in() {
        int x=0;char c=getchar();bool f=false;
        while(c<'0'||c>'9') f|=c=='-', c=getchar();
        while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48), c=getchar();
        return f?-x:x;
    }
    
    const int N = 1e5+5;
    
    int n, m, k, cur, pre[N], t[N<<1], blo, bl[N], ans[N];
    
    struct query {
        int l, r, id;
        inline friend bool operator < (const query &x, const query &y) {
            return bl[x.l]==bl[y.l]?x.r<y.r:x.l<y.l;
        }
    }q[N];
    
    inline void add(int u) {
        cur+=t[u^k];
        t[u]++;
    }
    
    inline void rem(int u) {
        t[u]--;
        cur-=t[u^k];
    }
    
    int main() {
        n=in(), m=in(), k=in();
        blo=(int)sqrt(n+1);
        for(int i=1;i<=n;++i) {
            bl[i]=(i-1)/blo+1;
            pre[i]=pre[i-1]^in();
        }
        for(int i=1;i<=m;++i) q[i]=(query){in()-1, in(), i};
        std::sort(q+1, q+1+m);
    
        for(int i=1, l=1, r=0;i<=m;++i) {
            for(;r<q[i].r;add(pre[++r]));
            for(;r>q[i].r;rem(pre[r--]));
            for(;l<q[i].l;rem(pre[l++]));
            for(;l>q[i].l;add(pre[--l]));
            ans[q[i].id]=cur;
        }
        for(int i=1;i<=m;++i) printf("%d
    ", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    NOIP 2012 T5 借教室 [洛谷P1083]
    POJ2437 Muddy roads
    POJ2288 Islands and Bridges
    洛谷P2014 TYVJ1051 选课
    POJ1741 Tree
    CODEVS1995 || TYVJ1863 黑魔法师之门
    TYVJ1939 玉蟾宫
    TYVJ1305 最大子序和
    POJ1737 Connected Graph
    TYVJ1864 守卫者的挑战
  • 原文地址:https://www.cnblogs.com/15owzLy1-yiylcy/p/10518315.html
Copyright © 2011-2022 走看看