首页 > 其他分享 >数列的异或和(题解)

数列的异或和(题解)

时间:2024-02-18 21:22:07浏览次数:19  
标签:数列 int 题解 add 二进制 异或 按位 前缀

题目

样例

  • 样例输入
    5 5
    1 2 3 4 5
    1 1 3
    1 3 5
    0 3 6
    1 1 3
    1 3 5
  • 样例输出
    0
    2
    5
    7

二进制运算

  • 二进制运算的优先级小于四则运算,所以在与四则运算同时出现时,注意加括号

按位与(&)

在二进制下,相同位的数都为1时,这一位的结果为1,任意一个不是1或都是0,则为0(eg:0100110&0010111=0000110->38&23=6)

  • a&1可以用来判断奇偶数(1->奇数;0->偶数)

按位或(|)

在二进制下,相同位的数只要有一个为1,这一位的结果为1(eg:10101|01010=11111->21+10=31)

*按位或在十进制下不能看做简单的加法

按位异或(∧)

在二进制下,相同位的数值相同,则为0,反之为1(eg:0100110∧0010111=0110001)

  • a∧a=0
  • a∧0=a

解题思路

首先1e5的数据范围暴力肯定是打不了(纯暴力过40分),所以要用树状数组进行优化(在别的题里叫用树状数组维护前缀和,我觉得在这个题里就叫维护前缀异或吧),下面给出代码

#include<bits/stdc++.h>
using namespace std;

const int maxn=20000100;

int n,m;
int sum[maxn],a[maxn];

//lowbit,add,getsum为树状数组的常规操作
int lowbit(int x)
{
    return x&(-x);
}

void add(int x,int y)
{
    while(x<=n)
    {
        sum[x]^=y;
        x+=lowbit(x);
    }
}

int getsum(int x)
{
    int num=0;
    while(x>0)
    {
        num^=sum[x];
        x-=lowbit(x);
    }
    return num;
}

int main()
{
    cin >>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin >>a[i];
        add(i,a[i]);//给前缀和(前缀异或)赋初值
    }
    int op,l,r;
    for(int i=1;i<=m;i++)
    {
        cin >>op>>l>>r;
        if(op==1)
        {
            int xx=getsum(r);
            int yy=getsum(l-1);
            int zz=xx^yy;
            cout <<zz<<endl;
        }
        else if(op==0)
        {
            int cnt=a[l]^r;
            //题目中为将a[x]改为y,所以要先运算一次
            add(l,cnt);
            a[l]=r;
        }
    }

    return 0;
}

标签:数列,int,题解,add,二进制,异或,按位,前缀
From: https://www.cnblogs.com/wang-qa/p/18019974

相关文章

  • 数列的异或和
    如果a^b=c,则c^a=b,c^b=aa^b=b^a,(a^b)^c=a^(b^c)a^b^b=a0^a=a,a^a=0数据:n:数列长度m:询问次数a[]:原数列c[]:树状数组函数:a[x]修改为yvoidadd(intx,inty){inti=x;while(i<=n){c[i]^=a[x];//还原......
  • 场景问题解决方法
    1.tomcatspringboot通过域名访问时直接跳到127.0.0.1的问题这种情况极可能是因为 server.xml配置问题导致,可以参考这篇文章tomcat设置http代理详细教程-知乎(zhihu.com)2.如何访问内网中所有的服务和站点要访问一个内网中所有的服务和站点(如内网的所有网站和数据库等),......
  • think-cell Round 1 题解 (A~F)
    think-cellRound1.目录A.MaximiseTheScore排序后输出所有奇数位之和.B.PermutationPrinting\(1,n,2,n-1\cdots\).C.LexicographicallyLargest注意到对于一个\(a_i\)来说\([a_i+1,a_i+i]\)中的所有数都可以被选中,那么问题变给若干区间,每个区间选一个数要......
  • [ARC122E] Increasing LCMs 题解
    Description给定长度为\(N\)的正整数序列\(\{A_i\}\),满足\(A_i\)单调升。问是否能将\(\{A_i\}\)重排为序列\(\{x_i\}\),满足:令\(y_i=\operatorname{LCM}(x_1,\dots,x_i)\),\(\forall1\lei<N,y_i<y_{i+1}\)(即\(y_i\)单调升)。$1\\leq\N\\leq\......
  • ABC341E 题解
    看到01串的反转考虑维护异或差分序列\(s_i=a_i\oplusa_{i-1}\)。这样区间反转就变成了单点修改。然后考虑怎么查询:若一个区间\([l,r]\)是好区间,那么对于\(i\in[l+1,r]\)一定存在\(s_i=1\)。所以我们可以查询区间和来判断是否为好区间。使用线段树维护区间和即可,单......
  • 11.【题解】最短母串
    最短母串hzoi题解题意给你几个字符串,给你密码长度,之后求出密码有多少种可能,其中如果方案数\(\leq42\),则需要按字典序输出所有方案。题解首先先求出每两个字符串的最大重合,记为\(\largerel{_i}{_,}{_j}\)(\(relation\),在枚举时使用。(其实应该用\(dfs\)),但蒟蒻太蒻......
  • HH的项链——题解
    题目描述直接求解会导致不同贝壳在上个区间算过但这个区间没标记的情况,所以在求解时要把上个区间的标记转移到这个区间转移前先右边界由小到大排序,然后转移上个右边界到这个右边界的标记,同时记录上个标记出现的地方,方便转移下面附代码solution#include<bits/stdc++.h>using......
  • 区间最大子区间和——山海经题解
    区间最大子区间和规定:ls:区间靠左部分子区间最大和rs:区间靠右部分子区间最大和ms:区间子区间最大和s:区间和方程与数量关系如图所示,可以用动态规划解决山海经题解这题是上述方法在线段树中的应用solution#include<bits/stdc++.h>usingnamespacestd;constintmax......
  • 寒假训练——vj题解
    B-BM算日期M是一位数学高手,今天他迎来了Kita的挑战。Kita想让BM算出这几年内有多少个闰年。BM觉得这问题实在太简单了,于是Kita加大了难度。他先给出第一个年份,再给出一个整数。Kita要BM进行加法运算后得到第二个年份,然后算出这两个年份之间有多少个闰年。然......
  • ABC341G 题解
    blog。妈的,被trick干爆了。\(\textbf{Trick}\):将所有\(N_i=(i,\sum\limits_{j=1}^ia_j)\)视作一点,则区间\([l,r]\)的平均值为\((N_{l-1},N_r)\)的斜率。\(\textbf{Prove}\):由\(\text{slope}=\dfrac{y_2-y_1}{x_2-x_1}\)易证。根据这个trick,\(k\)的答案即为\(k......