洛谷P9533 [YsOI2023] 区间翻转区间异或和

题目背景

Ysuperman 模板测试的数据结构题。

符卡可以是人名也可以是队名。

题目描述

符卡有一个长度为 n n n 的整数数组 a a a,符卡认为一个区间 [ l , r ] [l,r] [l,r] 是灵异区间当且仅当 ⨁ i = l r a i = 0 \bigoplus_{i=l}^ra_i=0 i=lrai=0,或者说这个区间内所有数字异或起来刚好等于 0 0 0

符卡有特殊的魔法,可以把任意一个灵异区间翻转。具体来说,如果 [ l , r ] [l,r] [l,r] 区间是灵异区间,那么符卡就可以对这个区间使用魔法,整个数组就会变成 a 1 , a 2 , … , a l − 1 , a r , a r − 1 , … , a l , a r + 1 , a r + 2 … , a n a_1,a_2,\dots,a_{l-1},a_r,a_{r-1},\dots,a_l,a_{r+1},a_{r+2}\dots,a_n a1,a2,,al1,ar,ar1,,al,ar+1,ar+2,an

现在符卡可以使用任意次数的魔法,符卡希望最后得到的数组的灵异区间数量能够尽可能多,你能告诉她最后最多有多少个灵异区间吗?

输入格式

第一行一个正整数 n n n,表示数组长度。

第二行 n n n 个非负整数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an 表示整个数组。

输出格式

输出一行一个整数,表示符卡使用任意次魔法后灵异区间最多有多少个。

样例 #1

样例输入 #1

3
1 1 1

样例输出 #1

2

样例 #2

样例输入 #2

4
3 1 2 3

样例输出 #2

2

提示

样例 1 解释

无论符卡发动多少次魔法,数组都是 1 , 1 , 1 1,1,1 1,1,1,所以发不发动魔法都没有任何关系。灵异区间永远都是 [ 1 , 2 ] , [ 2 , 3 ] [1,2],[2,3] [1,2],[2,3] 两个。

样例 2 解释

这里给出可能的一种魔法发动方法。

选择灵异区间 [ 1 , 3 ] [1,3] [1,3] 发动魔法,得到的新数组是 2 , 1 , 3 , 3 2,1,3,3 2,1,3,3,这个数组共有两个灵异区间,分别是 [ 1 , 3 ] [1,3] [1,3] [ 3 , 4 ] [3,4] [3,4]

可以证明答案无法超过 2 2 2

数据范围

对于前 20 % 20\% 20% 的数据,保证 n ≤ 10 n\le 10 n10

对于前 40 % 40\% 40% 的数据,保证 n ≤ 2000 n\le 2000 n2000

另有 10 % 10\% 10% 的数据,保证 a i a_i ai 全部相等。

另有 10 % 10\% 10% 的数据,保证 a i a_i ai 只有两种可能的取值。

另有 10 % 10\% 10% 的数据,保证 0 ≤ a i < 2 10 0\le a_i<2^{10} 0ai<210

对于 100 % 100\% 100% 的数据,满足 1 ≤ n ≤ 1 0 5 1\le n\le 10^5 1n105 0 ≤ a i < 2 20 0\le a_i< 2^{20} 0ai<220

彩蛋

灵异区间的名字其实是“零异(或)区间”的谐音。

这题是个经典前缀和,但处理完要异或,而且要开long long。
具体思路写代码里,这里就不做详解。

Code

#include <bits/stdc++.h>
using namespace std;
long long a[100050],b[100050];
int main(){
    long long n,s=0;
    map<int,int> c;//数组不够大,直接开map 
    cin>>n;
    c[0]=1;
    for(int i=1;i<=n;i++){
        cin>>a[i];//输入数字 
    }
    for(int i=1;i<=n;i++){
        b[i]=a[i]^b[i-1];//异或 
        s=s+c[b[i]];//记录答案 
        c[b[i]]++;
    }
    cout<<s;//输出 
    return 0;
}
  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值