题目:3.神奇的数组(蓝桥OJ 3000)

问题描述:

893c434eda0c49d9bbd17da13548a54f.png


解题思路:

        官方:

24e80a6237a647f9b0a92bbe88aff9cc.png

d9de3648448c4806a6055db5d069416f.png

         我的总结:

                        利用双指针遍历每个区间并判断是否符合条件:若一个区间符合条件则该区间在其左端点不变的情况下的每一个子区间都符合条件,相反若一个区间内左端点固定情况下有一个以其左端点为始的子区间不符合条件,则该区间不符合条件。因此可以先找到每一个左端点(即遍历完所有元素)固定情况下最远的右端点,(右端点减左端点)得出以该左端点为始有几个符合的区间,依次累加得总数及答案。

                        判断异或和等于算术和:算术运算没有进位时(二进制) ,(res ^ a[r]) == (res + a[r])。

        注意点:

                1.答案数据范围可能超过int,需要开long long。

                2.遍历的条件是l<n, r <n。不是l < r。

                3.左、右指针从第一个元素开始。

                4.因为r(右指针)每一次循环都增加,循环依次减少,所以该程序为O(n)。


题解:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9; 
int a[N];
using ll = long long;

int main()
{
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int n;cin >> n;
  for(int i = 0; i < n; i++)cin >> a[i];

  ll ans = 0;
  int l = 0, r = 0, res = 0;
  while(l < n){
      while(r < n && ((res ^ a[r]) == (res + a[r])))  // (res ^ a[r]) == (res + a[r])判断符合条件
      {  
        res ^= a[r];  // res:遍历的区间的异或和。
        r++;
      }
      ans += r - l;  // r -l:以该l为始的符合条件区间数
      res ^= a[l];  // 异或相消律:不同的消去。此行的作用是res刷新为a[l]
      l++;
  }

  cout << ans << '\n';
  return 0;
}

 知识点:

        双指针,二分查找,异或和与算术和,进位

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值