异或和之和

数论典题,拆成二进制位进行分析,首先用计算异或前缀和,便于区间操作,对于区间[L,R],其区间异或值为 Xor[L1]Xor[R],统计区间的在第 i 位为1的个数,那么根据乘法原理,有cnt1和剩余的0组合,然后这个是算出了有多少种方案让当前这一位有贡献,要算出答案需要对cnt[i] (n - cnt[i])乘以1 << k - 1(k表示枚举的是二进制下的第几位)

以下介绍两种做法:

#include<bits/stdc++.h> #define int long long using namespace std; const int N=2e6+10; int n,s[N],res; signed main(){ cin>>n; for(int i=1;i<=n;i++){ int x; cin>>x; s[i]=s[i-1]^x; } for(int i=0;i<=30;i++){ int cnt=0; for(int j=1;j<=n;j++) if((1<<i)&s[j]) cnt++; res+=(1<<i)*(n-cnt+1)*cnt; } cout<<res; }
#include<bits/stdc++.h> #define int long long using namespace std; const int N=2e6+10; int n,s[N],cnt1[N],cnt2[N],res; signed main(){ cin>>n; for(int i=0;i<=30;i++) cnt2[i]=1; for(int i=1;i<=n;i++){ int x; cin>>x; s[i]=s[i-1]^x; for(int j=30;j>=0;j--){ if((1<<j)&s[i]) res+=(1<<j)*cnt2[j],cnt1[j]++; else res+=(1<<j)*cnt1[j],cnt2[j]++; } } cout<<res; }

 


__EOF__

本文作者Sakurajimamai
本文链接https://www.cnblogs.com/o-Sakurajimamai-o/p/18003562.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   o-Sakurajimamai-o  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
-- --
点击右上角即可分享
微信分享提示