华北水利水电大学ACM第二届校赛题解

A: Xor and Sum

题目描述

给定一个大小为N的数组A,第i个元素为Ai

问有多少的子区间[LR],满足区间数值异或和等于区间数值和,即:

  1.      Axor Al+1 xor…xor AAAl+1 +…+Ar(l+1表示下标)
  2.       a和b的xor即为a和b二进制表示按位取xor得到新数c的十进制表示

5和12的xor计算如下:

510=01012

(12)10=(1100)2

01012xor11002=(1001)2

(1001)2=(9)10

输入


第一行给定一个整数N。
第二行给定N个整数,第i个数即为Ai。
1≤N≤2×10^5
0≤A_i≤2^30

输出

输出满足条件的子区间LR的数量。

样例输入

10
0 0 740 361 473 0 0 826 479 974

样例输出

18

思路:比赛的时候晃眼看了一下以为是数位dp什么的,就是没什么头绪。没做

赛后补题,挺妙的。

题解:

xor运算可以视为二进制下没有进位的加法,加法运算本身是有进位的加法。

那么可以简单得出这样一个性质:对于一个区间而言,如果异或和加法答案一样,那么把区间缩小答案肯定还是一样;如果异或和加法答案不一样,那么把区间扩大答案肯定还是不一样。

于是我们就可以枚举区间右端点,去寻找最小的左端点,这个区间异或等于区间和,那么以这个区间右端点的合法区间个数就是区间的长度(左端点往里缩都是合法的)。

这个可以预处理出前缀和还有前缀异或和,用双指针维护出来。

xor运算可以视为二进制下没有进位的加法,加法运算本身是有进位的加法。

那么可以简单得出这样一个性质:对于一个区间而言,如果异或和加法答案一样,那么把区间缩小答案肯定还是一样;如果异或和加法答案不一样,那么把区间扩大答案肯定还是不一样。

于是我们就可以枚举区间右端点,去寻找最小的左端点,这个区间异或等于区间和,那么以这个区间右端点的合法区间个数就是区间的长度(左端点往里缩都是合法的)。

这个可以预处理出前缀和还有前缀异或和,用双指针维护出来。

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<string>
#include<queue>
#include<stdlib.h>
#include<math.h>
#define per(i,a,b) for(int i=a;i<=b;++i)
#define rep(i,a,b) for(int i=a;i>=b;--i)
#define inf 0xf3f3f3f
#define ll long long int 
using namespace std;
int p[200005];
int s[200005];
int z[200005];
int main()
{
	int m,a;
	cin>>m;
	z[0]=0;s[0]=0;
	per(i,1,m) 
	{
		cin>>a;
		s[i]=s[i-1]+a;
		z[i]=z[i-1]^a;
	}
	ll l=0,sum=0;
	per(i,1,m)
	{
		while((z[i]^z[l])!=(s[i]-s[l])) l++;
		sum+=i-l;
	}
	cout<<sum;
	return 0;
}

B: 敲7

题目描述

输出7和7的倍数,还有包含7的数字的个数例如(17,27,37...70,71,72,73...)

输入

一个整数N。(N不大于30000)

输出

统计出不大于N的与7有关的数字的个数。如20以内与7有关的数为7、14、17共3个。

样例输入

20

样例输出

3

思路:水题,判一下就行。

C: 魔法扑克

题目描述

Yellowstar玩扑克总能立于不败之地,原因竟是他会使用魔法,每次使用魔法,能把手里的扑克变换成另一张扑克,但是使用魔法是非常消耗精力的,因此他不在万不得已的情况下不会轻易使用魔法。

某天Yellowstar打德州扑克输光了所有筹码,最后一轮,不得已他只好使用魔法。这轮他手里拿了5张牌,他需要使用魔法把这副牌变成同花顺,称五张牌构成了同花顺,当且仅当它们的数值连续,花色一致。

Yellowstar每次使用魔法能变换一张牌,他想知道最少他需要使用多少次魔法才能把牌变成同花顺。

扑克中一共有52种牌,牌的花色用一个大写字母'A' 'B' 'C' 'D'来表示,而数值用数字('1' '2' … '13')来表示。注意数字1代表ace,在德州扑克中是最大的牌。"1 2 3 4 5" 和 "10 11 12 13 1" 都被认为是连续的。而"11 12 13 1 2"并不是。

输入

第一行是样例数 1 <= T <= 1000
对于每组数据,在一行中有五个字符串代表五张牌。数据保证所有的牌都是不同的。

输出

输出T行,每行一个数表示最少需要使用几次魔法。
 

样例输入

5
A2 A3 A1 A4 A5
A1 A2 A3 A4 C5
A9 A10 C11 C12 C13
A11 A12 A13 A1 A2
B10 B11 B12 B13 B1

样例输出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值