题目描述

D. Mishka and Interesting sum的意思就是给出一个数组,以及若干询问,每次询问某个区间[L, R]之间所有出现过偶数次的数字的异或和。

这个东西乍看很像是经典问题,一列数字中所有数字出现偶数次,除了一个数字只出现一次,找出那个只出现过一次的数字。然而这个问题并不是要找出现奇数次数字的异或和。

算法

有一个直观的思路是求出[L, R的异或和,再异或上[L, R]之间所有出现过的数字的异或和。这样的话就可以使得数字出现次数的奇偶性发生变化。

那么怎么求出区间[L, R]所有出现过的数字的异或和呢?

先想一下如果是求区间[L, R]有多少种不同的数字怎么做?这个可以在遍历的时候保存每个数字最后出现的位置,打标记(去掉上一次的标记,更新到当前位置),去数[L, R]有多少个标记就行了。

所以求[L, R]不同数字的异或和也是类似的做法,去掉之前出现位置的标记,给当前位置打上标记,去计算[L,R]所有标记异或和。

回到原问题,有了区间不同数字的异或和,再异或上区间本身的异或值,就可以实现奇偶性翻转来得出出现偶数次的数字的异或和。

具体的流程:

需要一个异或BIT/FenwickTree,以及一个hashmap来保存元素出现位置。

按照所有询问的right值排序,遍历所有数字,每一次遍历到当前要处理的询问的R值为止。

每一步都要先往BIT中i位置加一个a[i](要做区间本身数字的异或)。

如果当前数字是第一次出现,则向BIT中i位置加一个a[i],hashmap中标记a[i]出现的位置为i。

如果当前数字之前已经出现过了,先去除上一次的标记,即向BIT中last[a[i]]加一个a[i](对于异或来说就抵消了),再向当前位置i加入一个a[i],更新hashmap中a[i]的位置为i。

可以发现,无论数字是否是第一次出现,最终hashmap中都得要给i这个位置加一个a[i],和上述每一个位置都要插入a[i]正好就抵消效果了。

所以流程可以简化为:每一步判断hashmap中是否存在a[i],存在的话取出位置值,BIT中往这个位置加a[i]。 在hashmap中插入<a[i], i>。

每一个询问的答案就是bit.query(R)^bit.query(L-1)

实现

public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
TaskD solver = new TaskD();
solver.solve(1, in, out);
out.close();
} static class TaskD {
public void solve(int testNumber, InputReader in, PrintWriter out) {
int n = in.nextInt();
long[] a = new long[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = in.nextLong();
}
int m = in.nextInt();
Query[] queries = new Query[m];
for (int i = 0; i < m; i++) {
queries[i] = new Query(i, in.nextInt(), in.nextInt());
}
Arrays.sort(queries, (o1, o2) -> Integer.compare(o1.right, o2.right));
Map<Long, Integer> pos = new HashMap<>();
FenwickTree tree = new FenwickTree(n) {
@Override
protected long operate(long data, long value) {
return data ^ value;
}
@Override
public long sum(int s, int t) {
return sum(t) ^ sum(s - 1);
}
};
int i = 1;
long[] result = new long[m];
for (Query query : queries) {
for (; i <= query.right; i++) {
if (pos.containsKey(a[i])) {
tree.add(pos.get(a[i]), a[i]);
}
pos.put(a[i], i);
}
result[query.id] = tree.sum(query.left, query.right);
}
for (long ret : result) {
out.println(ret);
}
} class Query {
int id;
int left;
int right; public Query(int id, int left, int right) {
this.id = id;
this.left = left;
this.right = right;
} } } static class InputReader {
private final BufferedReader reader;
private StringTokenizer tokenizer; public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream));
tokenizer = null;
} public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
} public int nextInt() {
return Integer.parseInt(next());
} public long nextLong() {
return Long.parseLong(next());
} } static class FenwickTree {
private final long[] data; public FenwickTree(int size) {
data = new long[size + 1];
} public FenwickTree(long[] data) {
this.data = data;
} private int lowBit(int x) {
return x & -x;
} protected long operate(long data, long value) {
return data + value;
} public final void add(int p, long v) {
for (int i = p; i < data.length; i += lowBit(i)) {
data[i] = operate(data[i], v);
}
} public final long sum(int p) {
long ret = 0;
for (int i = p; i > 0; i -= lowBit(i)) {
ret = operate(ret, data[i]);
}
return ret;
} public long sum(int s, int t) {
return sum(t) - sum(s - 1);
} }
}

CF #365 703D. Mishka and Interesting sum的更多相关文章

  1. Codeforces 703D Mishka and Interesting sum 离线+树状数组

    链接 Codeforces 703D Mishka and Interesting sum 题意 求区间内数字出现次数为偶数的数的异或和 思路 区间内直接异或的话得到的是出现次数为奇数的异或和,要得到 ...

  2. codeforces 703D Mishka and Interesting sum 偶数亦或 离线+前缀树状数组

    题目传送门 题目大意:给出n个数字,m次区间询问,每一次区间询问都是询问 l 到 r 之间出现次数为偶数的数 的亦或和. 思路:偶数个相同数字亦或得到0,奇数个亦或得到本身,那么如果把一段区间暴力亦或 ...

  3. Codeforces 703D Mishka and Interesting sum(离线 + 树状数组)

    题目链接  Mishka and Interesting sum 题意  给定一个数列和$q$个询问,每次询问区间$[l, r]$中出现次数为偶数的所有数的异或和. 设区间$[l, r]$的异或和为$ ...

  4. Codeforces 703D Mishka and Interesting sum(树状数组+扫描线)

    [题目链接] http://codeforces.com/contest/703/problem/D [题目大意] 给出一个数列以及m个询问,每个询问要求求出[L,R]区间内出现次数为偶数的数的异或和 ...

  5. CodeForces 703D Mishka and Interesting sum

    异或运算性质,离线操作,区间求异或和. 直接求区间出现偶数次数的异或和并不好算,需要计算反面. 首先,很容易求解区间异或和,记为$P$. 例如下面这个序列,$P = A[1]xorA[2]xorA[3 ...

  6. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

    题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...

  7. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

    转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...

  8. CF #365 DIV2 D Mishka and Interesting sum 区间异或+线段树

    D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...

  9. Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线+线段树

    题目链接: http://codeforces.com/contest/703/problem/D D. Mishka and Interesting sum time limit per test ...

随机推荐

  1. 2017-3-10 SQL server 数据库 T--SQL语句

    创建数据库:create datebase  数据库名     注:数据库名不能为中文,不能数字开头,不能符号开头. 删除数据库:drop datebase 数据库名 创建表:create   tab ...

  2. conky 1.10以后的新配置格式

    包装 config conky.config = { ... } 包装 TEXT conky.text = [[ ... ]] 每个 config 选项的变量和取值之间插入 "=" ...

  3. Solr field alias

    Field alias Any field, function, or transformer can be displayed with a different name in the output ...

  4. Intellij Idea自动加载改动文件和自动自动热部署加载

    1:准备原料 我的Intellij Idea的版本是15. 之后tomcat自动加载修,你只需要在浏览器刷新一下页面即可. ************************************** ...

  5. python——时间与时间戳之间的转换

    http://blog.csdn.net/google19890102/article/details/51355282

  6. 移动端高清、多屏适配方案——rem

    背景: 开发移动端H5页面 一套设计图 不同尺寸的手机 不同分辨率的手机 方案:使用rem作为单位解决一套设计图适应不同分辨率,不同尺寸的手机. 概念: REM(font size of the ro ...

  7. iOS开发之instancetype

    instancetype和id使用方法类似,但他们还有不同点: (1)instancetype在类型表示上,跟id一样,可以表示任何对象类型 (2)instancetype只能用在返回值类型上,不能像 ...

  8. nodejs 使用mongoose 操作mongodb

    nodejs操作mongodb可以使用mongoose: Mongoose is a MongoDB object modeling tool designed to work in an async ...

  9. Unity 3D Framework Designing(3)——构建View和ViewModel的生命周期

    > 对于一个View而言,本质上是一个MonoBehaviour.它本身就具备生命周期这个概念,比如,Awake,Start,Update,OnDestory等.这些是非常好的方法,可以让开发者 ...

  10. scipy安装问题

    刚开始使用pip安装的scipy,后来报了错误,具体意思是  numpy版本不支持. 在python.org.pypi 官网上的SciPy包是一个zip版本的,要使用与numpy相对应的后缀才行,也就 ...