题目链接:http://codeforces.com/contest/703/problem/D

给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少。

我们可以先预处理前缀和Xor[i],表示1~i的xor和。因为num^num=0,所以Xor[r] ^ Xor[l - 1]求的是l~r之间出现奇数次的数字xor和。

那怎么求偶数次的呢,那我们可以先求l到r之间不重复出现数字的xor(比如1 1 2 求的是1 ^ 2),然后再xor以上求出的Xor[r] ^ Xor[l - 1],奇奇消掉 就得出答案了。

那求不重复的话,我们用树状数组来处理。先把询问按照r从小到大排序,以便后面的离线处理。map存的是a[i]数字最近出现的位置i,然后用树状数组i位置插入a[i]并且消掉a[i]之前出现的位置i',这样保证查询不重复xor和最优。

具体看代码,应该能看懂。

 //#pragma comment(linker, "/STACK:102400000, 102400000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair <int, int> P;
const int N = 1e6 + ;
int bit[N], Xor[N], a[N], ans[N], n;
map <int, int> mp; //a[i]最近出现的位置
struct Query {
int l, r, id;
bool operator <(const Query& cmp) const {
return r < cmp.r;
}
}q[N]; void update(int i, int val) {
for(; i <= n; i += (i&-i))
bit[i] ^= val;
} int sum(int i) {
int s = ;
for(; i >= ; i -= (i&-i))
s ^= bit[i];
return s;
} int main()
{
int m;
scanf("%d", &n);
for(int i = ; i <= n; ++i) {
scanf("%d", a + i);
Xor[i] = Xor[i - ] ^ a[i]; //前缀xor
}
scanf("%d", &m);
for(int i = ; i <= m; ++i) {
scanf("%d %d", &q[i].l, &q[i].r);
q[i].id = i;
}
sort(q + , q + m + );
int j = ; //询问的结构体下标
for(int i = ; i <= n; ++i) {
int &temp = mp[a[i]]; //引用
if(temp) { //要是不是第一次出现,那就消掉a[i]之前出现的位置
update(temp, a[i]);
}
temp = i;
update(temp, a[i]); //插入最近的位置
while(j <= m && i == q[j].r) {
int l = q[j].l - , r = q[j].r;
ans[q[j].id] = sum(r) ^ sum(l) ^ Xor[r] ^ Xor[l];
++j;
}
}
for(int i = ; i <= m; ++i) {
printf("%d\n", ans[i]);
}
return ;
}

上面是正确的代码,下面是TLE的。

之前用莫队写的,数据小一点应该可以过。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
const int MAXN = 1e6 + ;
typedef __int64 LL;
int a[MAXN] , u, ans[MAXN];
struct que {
int l , r , id;
}q[MAXN];
map <int, int> mp; bool cmp(que x , que y) {
if(x.l / u == y.l / u)
return x.r < y.r;
return x.l / u < y.l / u;
} int main()
{
int n , m;
while(~scanf("%d" , &n)) {
for(int i = ; i <= n ; i++) {
scanf("%d" , a + i);
}
scanf("%d", &m);
for(int i = ; i <= m ; i++) {
scanf("%d %d" , &q[i].l , &q[i].r);
q[i].id = i;
}
u = (int)sqrt(n*1.0);
sort(q + , q + m + , cmp);
int L = , R = , num;
int temp = ;
for(int i = ; i <= m ; i++) {
while(R > q[i].r) {
num = --mp[a[R]];
if(num) {
temp ^= a[R];
}
R--;
}
while(R < q[i].r) {
R++;
num = ++mp[a[R]];
if(num > ) {
temp ^= a[R];
}
}
while(L < q[i].l) {
num = --mp[a[L]];
if(num) {
temp ^= a[L];
}
L++;
}
while(L > q[i].l) { //前面的还没算
L--;
num = ++mp[a[L]];
if(num > ) {
temp ^= a[L];
}
}
ans[q[i].id] = temp;
}
for(int i = ; i <= m ; i++) {
printf("%d\n", ans[i]);
}
}
return ;
}

Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)的更多相关文章

  1. Codeforces Round #365 (Div. 2)-D Mishka and Interesting sum(树状数组)

    题目链接:http://codeforces.com/contest/703/problem/D 思路:看了神犇的代码写的... 偶数个相同的数异或结果为0,所以区间ans[l , r]=区间[l , ...

  2. 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) ,问在每个区间里所有 ...

  3. 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 ...

  4. 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 ...

  5. Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)

    http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的 ...

  6. Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum 树状数组+离线

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

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

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

  8. Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum

    题目链接:传送门 题目大意:给n个数,m次询问,每次询问区间 l,r 内出现偶数次数的异或和 题目思路:前缀和+离线处理+树状数组 首先可以知道, l,r 内出现奇数次的数的和,就是把 l,r内所有数 ...

  9. Codeforces Round #510 (Div. 2) D. Petya and Array(离散化+反向树状数组)

    http://codeforces.com/contest/1042/problem/D 题意 给一个数组n个元素,求有多少个连续的子序列的和<t (1<=n<=200000,abs ...

随机推荐

  1. UVA 11383 Golden Tiger Claw(最佳二分图完美匹配)

    题意:在一个N*N的方格中,各有一个整数w(i,j),现在要求给每行构造row(i),给每列构造col(j),使得任意w(i,j)<=row(i)+col(j),输出row(i)与col(j)之 ...

  2. 同步内核缓冲区sync、fsync和fdatasync函数

    转自http://www.2cto.com/os/201409/339460.html 同步内核缓冲区 1.缓冲区简介 人生三大错觉之一:在调用函数write()时,我们认为该函数一旦返回,数据便已经 ...

  3. NHibernate实例化类部分属性

    NHibernate 为习惯SQL的开发者提供了接口,将查询的结果转变为持久化对象.虽然该方法不是很提倡. GetCurrentSession().CreateSQLQuery(sql) 参数sql就 ...

  4. 项目中使用的ajax异步读取数据结构设计

    设计稍微复杂了一点,完成ajax读取功能涉及到了很多页面.虽然如此,但感觉比较灵活. 和传统方法唯一的区别在于多了一层数据容器控件,里面提供了显示数据的HTML元素及相应的JS方法. 这样数据控件指生 ...

  5. 《Write Optimized B-Trees》读书报告

    论文原作者:Goetz Graefe, Microsoft.我读完这篇论文后颇有收获,所以写了一篇论文报告,旨在更精炼准确地阐述论文核心思想. 摘要:论文提出了一种方法,这种方法可以优化B树索引写性能 ...

  6. 1.解剖Linq to object

    LINQ想必大家都不陌生了,它的出现使得我们的代码变得更短.更优雅了.至于LINQ是什么,Linq to object这类的扩展方法到底做了些什么.我们使用的EF是如何实现的(如何解析Expressi ...

  7. SPF详解

    什么是SPF? 这里的SPF不是防晒指数,而是指Sender Policy Framework.翻译过来就是发信者策略架构,比较拗口,通常都直接称为SPF. SPF是跟DNS相关的一项技术,它的内容写 ...

  8. 讲解HTML服务器推送相关技术知识(转)

    1. 为什么需要服务器推送? 最大的优点:实时 健康知识平台重庆男科医院 重庆妇科医院适用场景:实时股票价格.商品价格.实时新闻.Twitter/weibo timeline.基于浏览器的聊天系统 2 ...

  9. <转>如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    原文链接:http://www.vaikan.com/use-multiple-cpu-cores-with-your-linux-commands/ 你是否曾经有过要计算一个非常大的数据(几百GB) ...

  10. Win7+VS2013初试Thrift

    win7环境下VS2013编译boost_1_58_0步骤: 官网下载boost_1_58_0(直接下载),解压 cmd窗口cd到boost_1_58_0,执行bootstrap.bat cmd窗口获 ...