【题解】



题意:

给n个数字组成有序数列;

给m个询问.

对于每个询问区间。输出这个区间里面出现次数为偶数次的所有数的异或值;

做法:

我们可以先求出这段区间里面所有(包括重复的数字)数字的异或值p1;

(出现次数为偶数的数x,这偶数个x的异或值为0(x^x==0),出现次数为奇数的数y(y^y^y==y),这奇数个数y的异或值为y,考虑到这些数字的和,那么剩下的其实就是出现次数为奇数次的所有数的异或值,也即p1);

然后我们再求出这段区间内不同的数字的异或值(去重)p2;

那么我们所需要的答案就是p1^p2;

因为异或了p2,所以p1中出现奇数次的数变成了偶数次->0,而原来出现偶数次的数变成出现奇数次->它本身);

则为我们所需的答案;

自己再想想吧.

然后就是求一段区间内不同的数字的总异或值的问题了。

这个问题可以用树状数组解决;

但是需要离线做;

把每个询问按照右端点升序排;

用map来判重;

枚举所有的数字;

到了一个新的数字;

就判断之前有没有出现过;

如果有出现过就把它之前的位置在树状数组中的相关值异或掉(相当于去除)。

然后给这个值设定一个新的位置(即当前的枚举到的位置);然后修改树状数组的相关位置.

然后如果有右端点和当前处理的数的位置相同。则用树状数组累加前缀异或值(不同的数).然后用一开始处理出的有重复数的前缀异或和和相应的东西异或就可以了。

要注意这道题里面异或有时就相当于减法.有时又相当于加法;

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map> using namespace std; const int MAXN = 1e6 + 100;
const int MAXM = 1e6 + 100; struct abc
{
int l, r, id;
}; int n, m;
int a[MAXN], c[MAXN], pre[MAXN];
int ans[MAXM];
abc Q[MAXM];
map <int, int> frequent; bool cmp(abc a, abc b)
{
return a.r < b.r;
} void input(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
} int lowbit(int x)
{
return x&(-x);
} void add(int pos, int what)//修改某个点,修改相关值
{
int x = pos;
while (x <= n)
{
c[x] ^= what;
x += lowbit(x);
}
} int sum(int pos)//累加前缀和
{
int x = pos;
int now = 0;
while (x > 0)
{
now = now^c[x];
x -= lowbit(x);//一直往左走
}
return now;
} int main()
{
input(n);
pre[0] = 0;
for (int i = 1; i <= n; i++)
input(a[i]), pre[i] = pre[i - 1] ^ a[i];
input(m);
for (int i = 1; i <= m; i++)
{
input(Q[i].l); input(Q[i].r);
Q[i].id = i;
}
sort(Q + 1, Q + 1 + m, cmp);//询问按照右端点升序排序
int now = 1;//now是当前处理到的询问
for (int i = 1; i <= n; i++)
{
if (frequent[a[i]])//如果之前出现过
add(frequent[a[i]], a[i]);//将之前的数字剔除
frequent[a[i]] = i;//然后更新这个数字的新位置;
add(frequent[a[i]], a[i]);//修改树状数组的相关点
while (now <= m && i == Q[now].r)//保证右端点之前记录的都是不同的数字的信息
{//用树状数组的前缀和获取这段区间内的不同数字的异或值
ans[Q[now].id] = sum(Q[now].r) ^ sum(Q[now].l - 1) ^ pre[Q[now].r] ^ pre[Q[now].l - 1];
now++;
}
}
for (int i = 1; i <= m; i++)
printf("%d\n", ans[i]);
return 0;
}

【29.82%】【codeforces 703D】Mishka and Interesting sum的更多相关文章

  1. codeforces 703D D. Mishka and Interesting sum(树状数组)

    题目链接: D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megaby ...

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

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

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

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

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

  5. 【 BowWow and the Timetable CodeForces - 1204A 】【思维】

    题目链接 可以发现 十进制4 对应 二进制100 十进制16 对应 二进制10000 十进制64 对应 二进制1000000 可以发现每多两个零,4的次幂就增加1. 用string读入题目给定的二进制 ...

  6. 树状数组【CF703D】Mishka and Interesting sum

    Description 给你n( 1<=n<=1000000)个数,以及m(1<=m<=1000000)个询问,每个询问包括l和r,问你在这n个数中,区间l~r,出现偶数个数的 ...

  7. CodeForces 703D Mishka and Interesting sum

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

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

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

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

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

随机推荐

  1. Altium Designer如何设置pcb尺寸

  2. 【MemSQL Start[c]UP 3.0 - Round 1 C】 Pie Rules

    [链接]h在这里写链接 [题意] 在这里写题意 [题解]     dp[i][0] 第i个位置,bob没有决策权     dp[i][1] 第i个位置,bob有决策权     dp[n][0] = 0 ...

  3. Android 中AIDL的使用与理解

    AIDL的使用: 最常见的aidl的使用就是Service的跨进程通信了,那么我们就写一个Activity和Service的跨进程通信吧. 首先,我们就在AS里面新建一个aidl文件(ps:现在AS建 ...

  4. maven 怎么在MyEclipse中打开Navigator视图

    方法一:1.点击菜单window2.选择show view菜单项3.选择other菜单项4.点击general,在其中可以找到 方法二:1.点击菜单window2.选择show view菜单项3.选择 ...

  5. 2、JNI说明

    JNI (Java Native Interface) 1. JAVA调用CLinux是用C语言写的,可以写一个APP简单调用open,read,write来访问驱动程序;Android是用Java写 ...

  6. 【u243】拓扑排序

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一些历史迷们打算把历史上的一些大事件按时间顺序列出来.但是,由于资料不全,每个事件发生的具体时间都没有 ...

  7. AndroidAnnotations使用说明书—AndroidAnnotations是怎样工作的?

    AndroidAnnotations的工作方式非常easy.它使用标准的java注入处理工具,自己主动加入了一个额外的编译步骤来生成源码. 源代码是什么?每个增强的类,比方每个用@EActivity注 ...

  8. [Pug] Template Engine -- Jade/ Pug

    Looking at the follow code: .wrapper - const upName = name && name.toUpperCase(); h2 | Hello ...

  9. [Docker] Build a Simple Node.js Web Server with Docker

    Learn how to build a simple Node.js web server with Docker. In this lesson, we'll create a Dockerfil ...

  10. php替换空格(php函数的设计思路)

    php替换空格(php函数的设计思路) 一.总结 1.替换和也是先查找了再替换,截取的话就是先查找到再截取 2.设计函数的时候按照的是缺省参数在后,核心东西在前的思路来设计函数的:查找的话是$sear ...