小AA的数列

小AA的数列

https://ac.nowcoder.com/acm/problem/14414

按位计算贡献

要求区间[l,r]的异或和,只需要知道[1,r]和[1,l-1]的异或和即可。
所以我们先对序列进行前缀异或和处理一下。这样可以O(1)计算任意一个子区间的异或和。
先不考虑要求偶数长度的限制,只考虑区间长度的限制。
我们知道 对于每一位而言,前缀异或和,该位要么是0要么是1,而要想对区间[l,r]对答案有贡献,则需要区间[1,r]和[1,l-1]的前缀异或和在该二进制位上的值相反。
那么这个很简单,我们只需要开一个cnt[0/1]数组统计每一二进制位上异或前缀和位0/1的个数。
那么要求长度是偶数呢?
容易知道奇+偶=奇、偶+偶=偶 所以cnt可以在多开一维 cnt[0/1][0/1]表示前缀异或和中 奇数/偶数位置的前缀和位0/1
那么枚举右端点j,以当前点为右端点的贡献就是,看有前缀中有多少个与到该二进制位的异或值相反(保证有贡献),并且在数列中的下标奇偶性相同(保证长度是偶数),在乘上1<<x即可(x为二进制的第x位)
如果当前枚举的右端点j大于r,那么就需要把最前面那个统计的cnt删除即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll cnt[2][2],a[1<<17];
int main()
{
    int n,l,r;
    cin>>n>>l>>r;
    for(int i=1;i<=n;i++) cin>>a[i],a[i]^=a[i-1];///前缀异或和
    ll ans=0;
    for(int i=0;i<32;i++){
        memset(cnt,0,sizeof cnt); //cnt第一维表示位置的奇偶性,第二维表示前缀异或和的值
        for(int j=l;j<=n;j++){
            cnt[(j-l)&1][(a[j-l]>>i)&1]++;///加入左端点  
            if(j>r)cnt[(j-r-1)&1][(a[j-r-1]>>i)&1]--;//删除在cnt中,最左边的那个点的贡献
            ans=(ans+cnt[j&1][((a[j]>>i)&1)^1]*(1ll<<i)%mod)%mod;///计算贡献
        }
    }
    cout<<ans;
    return 0;
}
每日一题 文章被收录于专栏

每日一题专栏

全部评论

相关推荐

985柜员:开发还敢还叫,全部让自测就老实了
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
正在热议
更多
# 大厂实习和小厂实习最大的区别是什么? #
2268次浏览 20人参与
# 参加完秋招的机械人,还参加春招吗? #
119926次浏览 760人参与
# 米连集团26产品管培生项目 #
14483次浏览 291人参与
# 牛友の3月总结 #
1790次浏览 24人参与
# 这些公司卡简历很严格 #
95208次浏览 417人参与
# 面试被问到不会的问题,你怎么应对? #
675次浏览 8人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
18778次浏览 302人参与
# 拼多多工作体验 #
52650次浏览 341人参与
# 研究所VS国企,该如何选 #
259038次浏览 2013人参与
# 通信硬件知识分享 #
48134次浏览 538人参与
# 找AI工作可以去哪些公司? #
17008次浏览 746人参与
# 从事AI岗需要掌握哪些技术栈? #
14870次浏览 841人参与
# 你做过最难的笔试是哪家公司 #
47344次浏览 750人参与
# 实习最想跑路的瞬间 #
130950次浏览 739人参与
# 金三银四,你的春招进行到哪个阶段了? #
24556次浏览 297人参与
# 说说你知道的学历厂 #
391003次浏览 1379人参与
# AI面会问哪些问题? #
36045次浏览 1071人参与
# 想给25届机械人的秋招建议 #
47737次浏览 251人参与
# 机械人避雷的岗位/公司 #
62887次浏览 395人参与
# 大厂无回复,继续等待还是奔赴小厂 #
343360次浏览 1988人参与
# 滴!实习打卡 #
814703次浏览 6858人参与
# 我心目中的理想工作是这样的 #
100873次浏览 907人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务