zoukankan      html  css  js  c++  java
  • CF703D Mishka and Interesting sum

    题意:给定一个1e6长度的值域1e9的数组。每次给定询问,询问区间内出现偶数次的数的异或和。

    题解:首先很显然,每一次询问的答案,等于这个区间所有不同元素异或和异或上区间异或和。(因为出现偶数次的对区间异或和贡献为0,此时剩下的是出现奇数次的数,在取个补集即为答案)

    区间异或和前缀和就好了,那问题转化为求区间不同元素异或和。由于这个东西区间合并很困难,所以在线算法是比较不优雅的。那我们考虑离线算法。我们按询问的右端点为第一关键字排序,然后处理到目前这个右端点位置的last数组,last数组定义为每个数最后出现的位置,然后给每个值对应的last附上它的值,这样我们一个区间求异或和可以得到区间不同元素异或和。树状数组一发就好了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1000000
     4 #define LL long long
     5 #define lowbit(x) ((x) & -(x))
     6 
     7 inline LL read() {
     8     LL x = 0, f = 1; char a = getchar();
     9     while(a < '0' || a > '9') { if(a == '-') f = -1; a = getchar(); }
    10     while(a >= '0' && a <= '9') x = x * 10 + a - '0', a = getchar();
    11     return x * f;
    12 }
    13 
    14 int n, a[N + 5], ans[N + 5], sum[N + 5], Q;
    15 int fen[N + 5];
    16 map<int, int> last;
    17 
    18 struct query {
    19     int id, l, r;
    20     bool operator < (const query & w) const {
    21         return r < w.r;
    22     }
    23 } q[N + 5];
    24 
    25 inline void add(int pos, int val) { if(!pos) return; for(int i = pos; i <= n; i += lowbit(i)) fen[i] ^= val; }
    26 
    27 inline int querysum(int l, int r) {
    28     int ret = 0;
    29     for(int i = r; i; i -= lowbit(i)) ret ^= fen[i];
    30     for(int i = l - 1; i; i -= lowbit(i)) ret ^= fen[i];
    31     return ret;
    32 }
    33 
    34 int main() {
    35     n = read();
    36     for(int i = 1; i <= n; i++) a[i] = read();
    37     for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] ^ a[i];
    38     Q = read();
    39     for(int i = 1; i <= Q; i++) q[i].id = i, q[i].l = read(), q[i].r = read();
    40     sort(q + 1, q + 1 + Q);
    41     for(int pos = 1, i = 1; i <= Q; i++) {
    42         for(; pos <= q[i].r; pos++) {
    43             add(last[a[pos]], a[pos]);
    44             last[a[pos]] = pos;
    45             add(pos, a[pos]);
    46         }
    47         ans[q[i].id] = querysum(q[i].l, q[i].r) ^ sum[q[i].l-1] ^ sum[q[i].r];
    48     }
    49     for(int i = 1; i <= Q; i++) printf("%d
    ", ans[i]);
    50     return 0;
    51 }
  • 相关阅读:
    Knockoutjs 实践入门 (2) 绑定事件
    HTTP If-Modified-Since引发的浏览器缓存汇总
    net.sf.json和 com.fasterxml.jackson中对象转json的区别
    JPA EntityManager详解
    Spring JPA中OneToOne和OneToMany用法
    Spring Data JPA中CrudRepository与JpaRepository的不同
    Git提交撤销
    Tomcat启动报StackOverflowError
    Git分支合并冲突解决(续)
    Git分支合并冲突解决
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6702708.html
Copyright © 2011-2022 走看看