题目链接: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. 属性readwrite,readonly,assign,retain,copy,nonatomic

    copy:建立一个索引计数为1的对象,然后释放旧对象 对NSString对NSString 它指出,在赋值时使用传入值的一份拷贝.拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议 ...

  2. id to load is required for loading----id被要求加载exception

    表示id主键 没有找到,可能是数据库中的主键设置了not null 而你没有给予主键 还有就是没有传递主键到 数据库中

  3. Java多线程-工具篇-BlockingQueue

    前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列 类,为我们快速搭建高质量的多线程程序带来极大的 ...

  4. RAC 之 RMAN 备份

    这篇主要介绍的是RAC 环境下的RMAN 备份. 关于Oracle 备份与恢复的一些理论知识参考我的Blog:       Oracle 备份 与 恢复 概述 http://blog.csdn.net ...

  5. 【模版消息】C#推送微信模版消息(Senparc.Weixin.MP.dll)

    定义的模版内容: {{first.DATA}} 商品名称:{{product.DATA}} 商品价格:{{price.DATA}} 购买时间:{{time.DATA}} {{remark.DATA}} ...

  6. min_free_kbytes

    http://kernel.taobao.org/index.php?title=Kernel_Documents/mm_sysctl min_free_kbytes 先看官方解释:This is u ...

  7. mongo 安装

    mongo 安装: 1.按照 https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/ 安装 2.安装成功后创建用户 d ...

  8. Free Candies

    题意: 有4堆东西,每堆有n个每个有一个颜色,现在有一个篮子最多能装5个不同的颜色的东西,每次都从堆顶拿,当篮子出现两个相同颜色,可以获得这两个东西,求获得的最大数量 分析: 因为就4推,可以把各堆的 ...

  9. 如何查看python selenium的api

    1. 打开命令行: command+R2. 输入: python -m pydoc -p 4567,然后:Enter3. 然后在浏览器中访问http://localhost:45674. 按ctrl+ ...

  10. loadrunner11录制不成功解决方法

    问题一:loadrunner11录制时events为0的解决办法  刚安装好的11.0,系统环境是:WIN7+IE11+LR11 1.ie去掉工具—internet选项中->高级—>去掉“ ...