题目链接: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. 如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)?

    Java time JavaScript Math.round(new Date().getTime()/1000) 之所以除以1000是因为getTime()返回数值的单位是毫秒 Microsoft ...

  2. 2012年7月12 – 腾讯公司 WEB高级应用开发工程师 最新面试题 [转]

    笔试(45 minute):(本来是四张纸,被我弄丢了一张!无伤大雅,难度级别不会有出入) 注意:由于时间紧迫和水平有限,难免有不足或错误,请指证,虚心学习! [PHP] 写出PHP中至少5个全局变量 ...

  3. HDU3232 Crossing rivers

    思路:这题关键一点就是根据题目的描述和测试数据得到启发,船都是 从对岸划过来的.心中有具体场景,就可以很简单了. #include<cstdio> int main() { ; ; whi ...

  4. ORACLE执行计划 explain说明

    ORACLE SQL优化工具系列之--EXPLAIN PLAN 对于oracle数据库来说,sql语句的优化可能是对性能提升最为明显的,当然对于DBA来说,也是挑战性比较大的.为了优化一个复杂的SQL ...

  5. Java自增原子性问题(测试Volatile、AtomicInteger)

    这是美团一面面试官的一个问题,后来发现这是一道面试常见题,怪自己没有准备充分:i++;在多线程环境下是否存在问题?当时回答存在,接着问,那怎么解决?...好吧,我说加锁或者synchronized同步 ...

  6. 前台实现下载xml功能

    阅读目录 介绍问题 MIME TYPE 解决问题 介绍问题 平时我们通过href去链接文件时,一般情况是对于zip.jar等下载功能,而对于xml.css.html.js等都是查看功能. 现在下面的代 ...

  7. python numpy argsort函数用法

    numpy.argsort numpy.argsort(a, axis=-1, kind='quicksort', order=None)[source] Returns the indices th ...

  8. phpmyadmin 设置用户登录

    找到 /opt/lampp/phpmyadmin/config.inc.php文件修改下面配置 这是原配置 #$cfg['Servers'][$i]['auth_type'] = 'config'; ...

  9. mysql 1130 ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server

    mysql -u root -p  mysql;use mysql;  mysql;select 'host' from user where user='root';  mysql;update u ...

  10. C/C++中static关键字详解-zz

    静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值. 静态变量或静态函数只有本文件内的代码才能访问它,它的名字在其它文件中不可见.用法1:函数内部声明 ...