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

题目传送门

题目大意:给出n个数字,m次区间询问,每一次区间询问都是询问 l 到 r 之间出现次数为偶数的数 的亦或和。

思路:偶数个相同数字亦或得到0,奇数个亦或得到本身,那么如果把一段区间暴力亦或,得到的其实就是出现次数为奇数的数字的亦或和,所以我们希望这段区间内的所有数字出现次数都+1,使奇偶性互换。

我们先处理出前缀的亦或和,这样可以得到次数为奇数的亦或和。

  接下来的问题就是要改变一段区间的奇偶性了,也就是说,这个问题其实就转化成了如何求一段区间出现的所有数字(无重复)。

这里我学到的是用树状数组离线处理的方式。核心代码如下。

  

    for(int i=1;i<=m;i++){
        while(p<=ask[i].r)
        {
            if(pos[a[p]]==0)//对于每一个第一次出现的数字,加入树状数组,并且记录。
            {
                pos[a[p]]=p;
                update(p,a[p]);
            }else
            {
                update(pos[a[p]],a[p]);//如果曾经出现过,则将之前的位置清空,更新树状数组和记录。
                update(p,a[p]);
                pos[a[p]]=p;
            }
            p++;
        }
        ask[i].ans=pre[ask[i].r]^pre[ask[i].l-1]^getxor(ask[i].r)^getxor(ask[i].l-1);
    }

如此操作后,比如我们询问的是1- R 的区间,此时肯定能得到我要的东西,但是如果我们询问的是1- r 这个区间的话(r<R),这个信息可能就不对了!!但是精彩的地方来了,由于我们事先对询问的区间排过序,也就是说,如果是纯粹的询问1-r区间,这个操作肯定在询问1-R之前,所以不会有影响,而如果我们计算的是r-R这个区间,此时1-r这个东西是出现在 减数 的位置的,也就是说,如果有一个数字在1-r和r-R中间都出现过,则此时1-r的树状数组为0,而1-R的树状数组为1!!

所以根据这个思路把他转化成亦或的求法就可以了。

接下来上代码。

#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<map>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1000010;
ll pre[maxn],tree[maxn<<2],a[maxn];
int n,m;
struct node{
    int l,r,id;
    ll ans;
}ask[maxn];
bool cmp(const node a,const node b)
{
    return a.r<b.r;
}
bool cmpid(const node a,const node b)
{
    return a.id<b.id;
}
inline int lowbit(int k){
    return (-k)&k;
}
inline void update(int x,ll val){
    while(x<=n){
        tree[x]^=val;
        x+=lowbit(x);
    }
}
inline ll getxor(int x){
    ll ans=0;
    while(x>0){
        ans^=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
map<ll,int >pos;
int main(){
    cin>>n;
    scanf("%lld",&a[1]);
    pre[1]=a[1];
    for(int i=2;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        pre[i]=pre[i-1]^a[i];
    }
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&ask[i].l,&ask[i].r);
        ask[i].id=i;
    }
    sort(ask+1,ask+1+m,cmp);
    int p=1;
    for(int i=1;i<=m;i++){
        while(p<=ask[i].r)
        {
            if(pos[a[p]]==0)
            {
                pos[a[p]]=p;
                update(p,a[p]);
            }else
            {
                update(pos[a[p]],a[p]);
                update(p,a[p]);
                pos[a[p]]=p;
            }
            p++;
        }
        ask[i].ans=pre[ask[i].r]^pre[ask[i].l-1]^getxor(ask[i].r)^getxor(ask[i].l-1);
    }
    sort(ask+1,ask+1+m,cmpid);
    for(int i=1;i<=m;i++)
    {
        printf("%lld\n",ask[i].ans);
    }
}

D. Mishka and Interesting sum

time limit per test

3.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present her with array of non-negative integers a1,?a2,?...,?an of n elements!

Mishka loved the array and she instantly decided to determine its beauty value, but she is too little and can‘t process large arrays. Right because of that she invited you to visit her and asked you to process m queries.

Each query is processed in the following way:

  1. Two integers l and r (1?≤?l?≤?r?≤?n) are specified — bounds of query segment.
  2. Integers, presented in array segment [l,??r] (in sequence of integers al,?al?+?1,?...,?ar) even number of times, are written down.
  3. XOR-sum of written down integers is calculated, and this value is the answer for a query. Formally, if integers written down in point 2 are x1,?x2,?...,?xk, then Mishka wants to know the value , where  — operator of exclusive bitwise OR.

Since only the little bears know the definition of array beauty, all you are to do is to answer each of queries presented.

Input

The first line of the input contains single integer n (1?≤?n?≤?1?000?000) — the number of elements in the array.

The second line of the input contains n integers a1,?a2,?...,?an (1?≤?ai?≤?109) — array elements.

The third line of the input contains single integer m (1?≤?m?≤?1?000?000) — the number of queries.

Each of the next m lines describes corresponding query by a pair of integers l and r (1?≤?l?≤?r?≤?n) — the bounds of query segment.

Output

Print m non-negative integers — the answers for the queries in the order they appear in the input.

Examples

input

Copy

33 7 811 3

output

Copy

0

input

Copy

71 2 1 3 3 2 354 74 51 31 71 5

output

Copy

03132

Note

In the second sample:

There is no integers in the segment of the first query, presented even number of times in the segment — the answer is 0.

In the second query there is only integer 3 is presented even number of times — the answer is 3.

In the third query only integer 1 is written down — the answer is 1.

In the fourth query all array elements are considered. Only 1 and 2 are presented there even number of times. The answer is .

In the fifth query 1 and 3 are written down. The answer is .

原文地址:https://www.cnblogs.com/mountaink/p/9794900.html

时间: 2024-08-13 02:12:56

codeforces 703D Mishka and Interesting sum 偶数亦或 离线+前缀树状数组的相关文章

Codeforces Round 261 Div.2 D Pashmak and Parmida&#39;s problem --树状数组

题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求有多少对这样的(i,j). 解法:分别从左到右,由右到左预处理到某个下标为止有多少个数等于该下标,用map维护. 然后树状数组更新每个f(j,n,a[j]),预处理完毕,接下来,从左往右扫过去,每次从树状数组中删去a[i],因为i != j,i不能用作后面的统计,然后统计getsum(inc[a[i]]-1), (inc表示从左到右),即查询比此时的a[i]

Codeforces Round #424 (Div. 2) D 思维 E set应用,树状数组

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) D. Office Keys 题意:一条直线上,有个办公室坐标 p,有 n个人在a[i],有 k把钥匙在b[i],每个人必须拿到一把钥匙,然后到办公室.问怎么安排花的时间最短. tags:还是不懂套路啊..其实多画两下图就能够感觉出来,2333 关键是要看出来,n个人拿的 n把钥匙应该是连续的. 然后,就是瞎暴力.. #include<bits/stdc++.h> usi

Codeforces Round #629 (Div. 3) F - Make k Equal (离散化 树状数组维护前缀和)

https://codeforces.com/contest/1328/problem/F 首先把a数组处理成pair对(num,cnt),表示数字num有cnt个,然后按num升序排序离散化一下. 对于一个数x,若想使得小于x的数字都变成x,必须先把所有小于x的数变成x-1,然后再+1变成x. 同理,要使得大于x的数变成x,必须把所有大于x的数字变成x+1,然后再-1变成x. 以上是题意所要求的必须操作. 思路: 1. 用f[i]数组记录离散化后前i大的数字的总数,那么对于任意第i大数字,可以

Codeforces Round #198 (Div. 1) D. Iahub and Xors 二维树状数组*

D. Iahub and Xors Iahub does not like background stories, so he'll tell you exactly what this problem asks you for. You are given a matrix a with n rows and n columns. Initially, all values of the matrix are zeros. Both rows and columns are 1-based,

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. The

Codeforces Round #301 (Div. 2) E. Infinite Inversions —— 逆序对 离散化 + 树状数组

题目链接:http://codeforces.com/contest/540/problem/E E. Infinite Inversions time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output There is an infinite sequence consisting of all positive integers in

Educational Codeforces Round 44 (Rated for Div. 2)+E. Pencils and Boxes+树状数组

题目链接:E. Pencils and Boxes 题意:N 个数,要求分成任意堆,要求每一堆只要有K个,同一堆中任意数之间差值不能超过d; 题解:用树状数组.排一下序然后从后面开始找,以当前数为最小值看能否成堆,要成堆的话要求i+k,到第一个大于a[i]+d的位置之间有能够成堆的位置.(这里判断的时候树状数组一减看是否大于0就可以了)注意初始化时在n+1的位置加1. 1 #include<bits/stdc++.h> 2 #include <iostream> 3 #includ

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

题目链接:传送门 题目大意:给n个数,m次询问,每次询问区间 l,r 内出现偶数次数的异或和 题目思路:前缀和+离线处理+树状数组 首先可以知道, l,r 内出现奇数次的数的和,就是把 l,r内所有数异或起来就是答案,那么出现偶数次的数就可以 先求出区间 l,r 内有多少不同的数,将这些数异或起来,再异或上区间内出现奇数次的数的异或和就是答案.(出现偶数次的数异或后为0,奇数次的数异或后是本身   然后离线处理询问,对询问按右端点 sort,因为树状数组保存的是数出现的最后位置.离线处理询问后便

Codeforces Gym 100114 H. Milestones 离线树状数组

H. Milestones Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Description The longest road of the Fairy Kingdom has n milestones. A long-established tradition defines a specific color for milestones in each region, with a