CF703D. Mishka and Interesting sum

本文介绍了一道关于区间中出现偶数次元素异或和的问题,并提供了一个高效的算法解决方案。通过离线处理和线段树数据结构,实现快速查询更新操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给一个长度为n的序列,m次询问,询问为区间中所有出现了偶数次的数的异或和。

题解:由于区间的异或和剩下的是出现奇数次的数,每次询问的答案即为 x^y  x=区间内所有出现了的数的异或和 y=区间内出现了奇数次的数的异或和.如果在线询问的话x不好维护。所以离线处理,如果这个数出现过就抹去之前出现的点,保证每个数只出现一次。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
using namespace std;
#define maxn 4001000
#define pb push_back
#define mp make_pair
#define ft first
#define sd second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define getmid int mid=(l+r)>>1
map<int,int>myp;
vector<pair<int,int> >g[maxn];
int ans[maxn];
int siz,n,pre[maxn],xorsum[maxn],a[maxn],m;
void pushup(int rt)
{
    xorsum[rt]=xorsum[rt<<1]^xorsum[rt<<1|1];
}
int query(int l,int r,int rt,int st,int ed)
{

    if(st<=l&&r<=ed)
    {
        return xorsum[rt];
    }
    getmid;
    int t1=0,t2=0;
    if(st<=mid)
        t1=query(lson,st,ed);
    if(ed>mid)
        t2=query(rson,st,ed);
    return t1^t2;
}
void update(int l,int r,int rt,int pos,int f)
{
    if(l==r)
    {
        xorsum[rt]^=f;
        return;
    }
    getmid;
    if(pos<=mid) update(lson,pos,f);
    else update(rson,pos,f);
    pushup(rt);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        pre[i]=pre[i-1]^a[i];
    }
    int l,r;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        g[r].pb(mp(l,i));
    }
    int ll,rr;
    for(int i=1;i<=n;i++)
    {
        if(myp[a[i]]!=0) update(1,n,1,myp[a[i]],a[i]);
        update(1,n,1,i,a[i]);

        myp[a[i]]=i;
        rr=i;
        for(int j=0;j<g[i].size();j++)
        {
            ll=g[i][j].ft;
            ans[g[i][j].sd]=pre[rr]^pre[ll-1]^query(1,n,1,ll,rr);
        }
    }
    for(int i=1;i<=m;i++)
    {
        printf("%d\n",ans[i]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值