Soratosorato

ABC365E Xor Sigma Problem 题解

Sorato·2024-08-07 01:03·97 次阅读

ABC365E Xor Sigma Problem 题解

ABC365E Xor Sigma Problem 题解

题目大意#

给定长度为 n 的序列 A,求 i=1N1j=i+1N(AiAi+1Aj)

Solve#

看到异或不难想到按位枚举,按位枚举时维护什么信息呢?

考虑对于序列 A,我们倒序枚举,那么在加入 Ai 之前得到的区间异或和之和形如:

(Ai+1Ai+2An)+(Ai+1Ai+2An1)++(Ai+1Ai+2)

加入 Ai 后,这个表达式的每个括号里都要异或上 Ai。那么从结果上看,若 Ai 的第 j 位是 1,则异或和的第 j 位就要反转。

故我们考虑维护如下信息:对于第 i 位,cnti,1 表示有多少段异或和(上式中每一个括号内的值)这一位是 1cnti,0 表示有多少段异或和这一位是 0。统计答案时直接加上 2i×cnti,1 即可。

加入 Ai 后,按位扫一遍,如果 Aij 位是 1,就交换 cntj,0cntj,1。同时别忘了,加入 Ai1 时多了一段 Ai1Ai,故我们还要让 cntj,Ai,j 加上 1 方便后面统计答案。

Code#

Copy
#include<bits/stdc++.h> using namespace std; #define int long long inline int read() { short f=1; int x=0; char c=getchar(); while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } const int N=2e5+10; int n,a[N],ans,cnt[35][2]; signed main() { n=read(); for(int i=1;i<=n;i=-~i) a[i]=read(); for(int i=n;i;i--) { for(int j=30;j>=0;j--) ans+=cnt[j][(a[i]>>j&1)^1]*(1<<j); for(int j=30;j>=0;j--) { if(a[i]>>j&1) swap(cnt[j][1],cnt[j][0]); cnt[j][a[i]>>j&1]++; } } return printf("%lld",ans),0; }
posted @   Sorato  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示
目录