题目链接: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. python 包管理

    如果导入的模块和主程序在同个目录下,直接import就行了 2.如果导入的模块是在主程序所在目录的子目录下,可以在子目录中增加一个空白的__init__.py文件,该文件使得python解释器将子目录 ...

  2. greensock的tween源码阅读笔记

    对于一个处于gc状态的tween,如果这个gc状态是由kill触发的,那么直接从masterList删除否则的话,被tweenlite的垃圾回收删除! 对于一个不是立即启动的tween,它被添加到ti ...

  3. RMAN duplicate from active遇到ora-17167,ora-12154

    最近在从活动数据库进行异机克隆时碰到了ORA-17629,ORA-17627,ORA-12154的错误,起初以为是一个Bug呢.Oracle Bug着实太多了,已经成了习惯性思维了.汗!错误提示是无法 ...

  4. OpenGL学习之路(三)

    1 引子 这些天公司一次次的软件发布节点忙的博主不可开交,另外还有其它的一些事也占用了很多时间.现在坐在电脑前,在很安静的环境下,与大家分享自己的OpenGL学习笔记和理解心得,感到格外舒服.这让我回 ...

  5. 组合 z

    输入a b c d e以及它们对应的数字 比如 a-->1 2 3  b-->2 3 c-->1 d-->3 4 5 e-->1 3 5 输出a b c d e的可用组合 ...

  6. Range类中的三个方法及简单打印

    package pkgFirst; import org.junit.Test; public class Range{ /** * FunName: println * Description : ...

  7. 我常用的Linux命令

    CD: ..        —-切换到上层目录 ~        —-回到家目录(/home/你的登录名/) LS: -a        —-显示指定目录所有文件,包括文件名以 . 开头的文件 -l  ...

  8. matlab 调用VLfeat库开篇问题

    准备工作见此网站 :http://cnyubin.com/?p=85 保存关闭startup.m文件后 重新打开matlab后 在命令行输入path或者vl_version无法检测到库已安装到matl ...

  9. 一.JSP开发的工具下载与环境搭建

    JSP技术的强势: (1)一次编写,到处运行.在这一点上Java比PHP更出色,除了系统之外,代码不用做任何更改. (2)系统的多平台支持.基本上可以在所有平台上的任意环境中开发,在任意环境中进行系统 ...

  10. 线程局部变量ThreadLocal的原理及使用范围_1

    线程局部变量ThreadLocal的原理及使用范围 使用原理 每个Thread中都有一个ThreadLocalMap成员, 该成员是ThreadLocal的内部类ThreadLocalMap类型.每使 ...