codeforces703D Fenwick tree different offline processing interval and the XOR element

The meaning of problems

For n digits, m interrogation times, xor even-number range of l ~ r all occurrences

Thinking

Xor section and can be obtained by the prefix: sum []

Depending on the nature of the xor, the SUM [] is the number of occurrences of interval is an odd number and xor

If we want to be an even number of occurrences of all the books and XOR, just above calculated on the sum [] * [this paragraph for each different numbers appear xor] , easy to see, which achieved an odd number and conversion between the even-numbered xor xor.

Now, we need to find [this paragraph different numbers for each occurrence of xor]  With BIT discrete process:

First, in accordance with the right border Sort query from small to large, analog pointer p, m times to traverse the interrogation right boundary: map <int, int> mapping relationship recorded in the tree and the location numbers, each number modification process is maintained as far as the right, while the previous occurrence becomes 0, ans = sum [r] ^ sum [l - 1] ^ query (r) ^ query (l - 1); correctness thus guaranteed because in this range the query within each digit must mean there was once.

ACcode

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>

using namespace std;
const int MaxN = 1e6 + 5;
typedef long long LL;

int n,q;
int aa[MaxN],sum[MaxN],tree[MaxN];

map<int,int> mp;//number - position

struct NODE{
	int l,r,pos;
	int ans;
}a[MaxN];

bool cmp(NODE A,NODE B){
	return A.r < B.r;
}

bool CMP(NODE A,NODE B){
	return A.pos < B.pos;
}

//BIT's part
int lowbit(int t){
	return t & (-t);
}

void update(int pos,int Xor){
	while(pos <= n){
		tree[pos] ^= Xor;
		pos += lowbit(pos);
	}
}

int query(int pos){
	int Ans = 0;
	while(pos){
		Ans ^= tree[pos];
		pos -= lowbit(pos);
	}
	return Ans;
}


int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n; i++) scanf("%d",&aa[i]);
	scanf("%d",&q);
	for(int i = 1;i <= q; i++){
		scanf("%d %d",&a[i].l,&a[i].r);
		a[i].pos = i;
	}
	for(int i = 1;i <= n; i++) sum[i] = sum[i - 1] ^ aa[i];

	sort(a + 1,a + 1 + q,cmp);
	int p = 1;//单调指针
	//替换过程这一坨是O(n)
	for(int i = 1;i <= q; i++){
		int l = a[i].l,r = a[i].r;
		while(p <= r){//
			if(mp[aa[p]]){
				update(mp[aa[p]],aa[p]);
				update(p,aa[p]);
				mp[aa[p]] = p;
			}
			else{
				update(p,aa[p]);
				mp[aa[p]] = p;
			}
			p++;
		}
		a[i].ans = sum[r] ^ sum[l - 1] ^ query(r) ^ query(l - 1);
	}

	sort(a + 1,a + 1 + q,CMP);
	for(int i = 1;i <= q; i++){
		printf("%d\n",a[i].ans);
	}
}

 

Published 31 original articles · won praise 5 · Views 1363

Guess you like

Origin blog.csdn.net/qq_43685900/article/details/103174884