1. 程式人生 > >codeforces 703D Mishka and Interesting sum 偶數亦或 離線+前綴樹狀數組

codeforces 703D Mishka and Interesting sum 偶數亦或 離線+前綴樹狀數組

rmi data 一個 day 得到 地方 operator 每一個 思路

題目傳送門

題目大意:給出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
3
3 7 8
1
1 3
output Copy
0
input Copy
7
1 2 1 3 3 2 3
5
4 7
4 5
1 3
1 7
1 5
output Copy
0
3
1
3
2
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 技術分享圖片.

codeforces 703D Mishka and Interesting sum 偶數亦或 離線+前綴樹狀數組