zoukankan      html  css  js  c++  java
  • CF #365 (Div. 2) D

    题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum

    题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值。

    思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了。

    第一个问题:得到询问区间的所有数的异或值,由 a[1~r] ^ a[0~(l-1)] = a[l~r] 可以用数组all_xor[i]保存a[1~i]区间的所有数的异或值,每次对询问区间的左右断点的all_xor值异或即可。

    第二个问题:得到该区间内所有出现过的数的异或值,离线树状数组。具体操作如下:

    先按照询问的右区间保存所有的询问g[r].(l, id),当前询问的结果保存在ans[id]里。

    用树状数组one_xor[i]保存a[1~i]区间所有出现过的数(只统计一次)的异或值。遍历a[i],如果a[i]出现过了,对于后面的询问,右区间一定是>=i的,即i之前的区间都已经不关心这个值是否出现过了,

    add_xor(mp[a[i]], a[i]),使前面的区间不再有这个数。然后mp[a[i]] = i , add_xor(mp[a[i]], a[i]) ; 这样保证了后面的每次询问都只在该最近一次出现过a[i]值的地方找到a[i]。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <vector>
    #include <map>
    #define maxn 1000010
    using namespace std;
    
    int a[maxn], one_xor[maxn], ans[maxn], all_xor[maxn]; //分别对应 原数组 (0~i)所有出现过的数的异或 保存ans (0~i)所有的数的异或
    
    struct Query {
        int l, id;
    };
    
    map<int, int>mp;
    vector<Query> query[maxn];
    int n, m;
    
    void init() {
        mp.clear();
        for (int i=1; i<=maxn; ++i) {
            query[i].clear();
        }
        memset(one_xor, 0, sizeof(one_xor));
    }
    
    void add_xor(int x, int val) {
        for (; x<=n; x+=(x&(-x)))
            one_xor[x] ^= val;
    }
    
    int sum_xor(int l, int r) {
        int ans = 0;
        for (; r>0; r-=(r&(-r))) ans ^= one_xor[r];
        for (; l>0; l-=(l&(-l))) ans ^= one_xor[l];
        return ans;
    }
    
    int main(){
        //freopen("in.cpp", "r", stdin);
        while(~scanf("%d", &n)) {
            init();
            all_xor[0] = 0;
            for (int i=1; i<=n; ++i) {
                scanf("%d", &a[i]);
                all_xor[i] = all_xor[i-1]^a[i];
            }
            scanf("%d", &m);
            for (int i=1; i<=m; ++i) {
                int l, r;
                scanf("%d%d", &l, &r);
                query[r].push_back({l, i});
            }
    
            for (int i=1; i<=n; ++i) {
                if (mp.count(a[i])) {
                    add_xor(mp[a[i]], a[i]);
                }
                mp[a[i]] = i;
                add_xor(mp[a[i]], a[i]);
    
                for (int j=0; j<query[i].size(); ++j) {
                    Query now = query[i][j];
                    ans[now.id] = (all_xor[i] ^ all_xor[now.l-1]);
                    ans[now.id] ^= sum_xor(i, now.l-1);
                }
            }
    
            for (int i=1; i<=m; ++i) {
                printf("%d
    ", ans[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    一个大浪Java罢工(一个)安装JDK和环境变量配置
    awk的实施例
    【phpMyAdmin】更改配置文件连接到其他server
    Humming Bird A20 SPI2驱动编译
    2014Esri国际用户大会ArcGIS Online
    POJ 2724 Purifying Machine(最大独立集)
    python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹
    《java系统性能优化》--2.高速缓存
    XAMPP on Mac 组态 Virual Host
    Explicit keyword
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5744409.html
Copyright © 2011-2022 走看看