CodeForces 703D Mishka and Interesting sum(线段树+异或)

给定一个数列,m次查询 每次查询输出某个区间的出现数字为偶数的数字的异或

对于异或可以知道,偶数个相同数字异或为本身,那么我们容易知道 对于询问 q[l,r]=y[l,r]^c[l,r]

q为某个区间出现次数为偶数的数字异或

y为某个区间异或之和

c为某个区间所有不相同的数字的异或之和


对于y我们可以预处理出来 O(1)查询

对于不同数字的异或  我们用线段树来查询


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <stack>
#include <queue>
#include <string.h>
#include <string>
#include <iomanip>
#include <cstring>
#include <vector>
#include <functional>
#include <cmath>
#include <sstream>
#include<complex>
#include <set>
//#include<bits/stdc++.h>

using namespace std;
#define sp system("pause")
typedef long long ll;
typedef unsigned long long ull;
const ll mod = 1000000007;
#define PI acos(-1.0)
#define eps 1e-6

using namespace std;
#define INF 0x73737373
#define EPS 1e-8
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define MAXN 1000010
int sum[MAXN << 2], A[MAXN], ans[MAXN << 2];
map <int, int> hsh;

struct Query_Node
{
	int l, r, index;
	friend bool operator < (Query_Node a, Query_Node b)
	{
		return a.r < b.r;
	}
}q[MAXN << 2];
void push_up(int rt)
{
	sum[rt] = sum[rt << 1 | 1] ^ sum[rt << 1];
}
void update(int l, int r, int rt, int p, int val)
{
	if (l == r)
	{
		sum[rt] ^= val;
		return;
	}
	int m = (l + r) >> 1;
	if (p <= m) update(lson, p, val);
	else update(rson, p, val);
	push_up(rt);
}
int query(int l, int r, int rt, int L, int R)
{
	if (L <= l && R >= r)
		return sum[rt];
	int m = (l + r) >> 1;
	int ret = 0;
	if (L <= m) ret ^= query(lson, L, R);
	if (R > m) ret ^= query(rson, L, R);
	return ret;
}

int dp[1000000 + 100];
int main()
{
	int t;
	t = 1;
	while (t--)
	{
		int n, m;
		hsh.clear();
		memset(sum, 0, sizeof(sum));
		memset(dp, 0, sizeof dp);
		scanf("%d", &n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &A[i]); dp[i] = dp[i - 1] ^ A[i];
		}
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
		{
			scanf("%d%d", &q[i].l, &q[i].r);
			q[i].index = i;
		}
		sort(q, q + m);
		int pos = 1;
		for (int i = 0; i < m; i++)
		{
			for (; pos <= n && pos <= q[i].r; pos++)
			{
				if (hsh[A[pos]]) update(1, n, 1, hsh[A[pos]], A[pos]);
				update(1, n, 1, pos, A[pos]);
				hsh[A[pos]] = pos;
			}
			ans[q[i].index] = query(1, n, 1, q[i].l, q[i].r);
			ans[q[i].index] ^= (dp[q[i].r] ^ dp[q[i].l - 1]);
		}
		for (int i = 0; i < m; i++)
			printf("%d\n", ans[i]);
	}
	//sp;
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值