zoukankan      html  css  js  c++  java
  • 【CQOI2018】异或序列

    题目描述

    已知一个长度为n的整数数列 $a_1,a_2,...,a_n$​,给定查询参数l、r,问在 $a_l,a_{l+1},...,a_r$​ 区间内,有多少子序列满足异或和等于k。也就是说,对于所有的 x,y $(lle xle yle r)$,能够满足$a_xigoplus a_{x+1} igoplus ... igoplus a_y = k$ 的 x,y 有多少组。

    思路

    记一个异或前缀和 val,问题就转换成有多少对数异或等于 k
    直接上莫队

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100000 + 10;
    int n,m,k,block,cnt[maxn],val[maxn];
    long long tot,ans[maxn];
    struct Query {
        int l,r,num;
        inline bool operator < (Query cmp) const {
            if (l/block != cmp.l/block) return l/block < cmp.l/block;
            return r/block < cmp.r/block;
        }
    }q[maxn];
    inline void add(int x) { tot += cnt[x^k]; cnt[x]++; }
    inline void del(int x) { tot -= cnt[x^k]+(!k); cnt[x]--; }
    int main() {
        scanf("%d%d%d",&n,&m,&k);
        block = sqrt(n);
        for (int i = 1;i <= n;i++) scanf("%d",&val[i]),val[i] ^= val[i-1];
        for (int i = 1;i <= m;i++) {
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].l--;
            q[i].num = i;
        }
        sort(q+1,q+m+1);
        int l = 1,r = 0;
        for (int i = 1;i <= m;i++) {
            while (l > q[i].l) add(val[--l]);
            while (l < q[i].l) del(val[l++]);
            while (r < q[i].r) add(val[++r]);
            while (r > q[i].r) del(val[r--]);
            ans[q[i].num] = tot;
        }
        for (int i = 1;i <= m;i++) printf("%lld
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    文本框字数减少
    区分兼容IE6/IE7/IE8/IE9/FF的CSS HACK写法
    将浏览器兼容代码标明信息并相互分开
    JavaScript正则表达式
    CSS3 @font-face
    iOS 获取手机的使用存储信息
    升级 ox 10.11的系统以后执行 pod install 的时候报错
    Xcode7安装模拟器
    iOS-视图生命周期
    Xcode升级插件失效修复快捷方式
  • 原文地址:https://www.cnblogs.com/lrj124/p/8986001.html
Copyright © 2011-2022 走看看