1054D - Changing Array(贪心)
题目
题意
-
输入正整数 n(≤2e5) k(≤30) 和长为 n 的数组 a(0≤a[i]≤pow(2,k)-1)。
-
设 mask = (1<<k)-1,每次操作你可以把任意 a[i] 修改为 a[i] XOR mask,你可以操作任意次(包括 0 次)。
-
修改后,最多有多少个 a 的非空连续子数组,其异或和不等于 0?
思路
- 找最多的不为 0 ,不方便,转化为找最少的为0
- 需要从异或前缀和出发,找一段连续子数组异或和为 0 非常方便,
- 修改一个数字为 a[i] XOR mask,那么前缀异或i后面都异或mask,所以就变为一段一段奇数为 a[i] 偶数为 a[i] XOR mask的数组
- 再进一步,想要最灵活的修改数组,其实一个一个也可以
- 最后,只要让 a[i] 和 a[i] XOR mask 数量平均就可以实现最小(简单数学)
- 不要忘记在前缀意义上的起点 0 ,初始时 cnt[0] = 1
代码
const int N = 2e5+10;
int a[N];
void solve()
{
int n,k;cin >> n >> k;
for(int i = 1;i <= n;i ++)cin >> a[i],a[i] ^= a[i-1];
const int mask = (1 << k) - 1;
map<int,int> cnt;
for(int i = 0;i <= n;i ++)
{
int flip = a[i] ^ mask;
if(cnt[a[i]] <= cnt[flip])cnt[a[i]] ++;
else cnt[flip] ++;
}
LL ans = 0;
for(auto [x,y]:cnt)
{
ans += 1LL*y*(y-1)/2;
// debug2(x,y);
}
cout << 1LL*n*(n+1)/2 - ans << endl;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析