首页 > 其他分享 >从CF1879D学习一类区间贡献题思路

从CF1879D学习一类区间贡献题思路

时间:2024-06-15 16:32:42浏览次数:27  
标签:std cnt CF1879D 32 sum times 区间 思路 oplus

https://codeforces.com/contest/1879/problem/D

关键在于互换两个 \(\sum\)​ 的顺序

一般像这样计算所有子区间的式子,如果要优化成接近线性,有一种可行思路是把注意力放在右端点,通过不断移动右端点,在移动的时候利用前面的统计结果算出移动右端点后的结果,从而得出所有子区间的答案。然后还有一个显然有用的套路是前缀和,这里记 $s_i=a_1 \oplus a_2\oplus ···\oplus a_{n-1}\oplus a_n $ ,\(s_{i,j}\) 为 \(s_i\) 二进制的第 \(j\) 位,我们会发现 \(\sum_{l=1}^{n}\sum_{r=l}^{n}f(l,r)=\sum_{i=0}^{32}\sum_{l=1}^{n}\sum_{r=l}^{n}s_{l,i} \oplus s_{r,i}\times 2^i\)

由于上面的式子可以优化成 \(O(n\operatorname{log}V)\),我们受到启发推出下面的式子

\(\sum_{l=1}^{n}\sum_{r=l}^{n}f(l,r)\times(r-l+1)\)

\(=\sum_{r=1}^{n}\sum_{l=1}^{r}f(l,r)\times(r-l+1)(调换∑位置)\)

\(=\sum_{r=1}^{n}\sum_{l=1}^{r}\sum_{i=0}^{32} s_{l,i} \oplus s_{r,i}\times 2^i\times(r-l+1)\)

\(=\sum_{r=1}^{n}\sum_{i=0}^{32} \sum_{l=1}^{r}[ s_{r,i}\oplus s_{l,i} =1]\times 2^i\times(r-l+1)\)

\(=\sum_{r=1}^{n}\sum_{i=0}^{32} 2^i\times\sum_{l=1}^{r}([ s_{r,i}\oplus s_{l,i} =1]\times r-[ s_{r,i}\oplus s_{l,i} =1] \times (l-1))\)

把 \(r\)​ 视作常量再观察上面的式子,你就会发现最后一维可以被优化掉,因为 $\displaystyle \sum_{l=1}^{r}[ s_{r,i}\oplus s_{l,i} =1]\times r $​ 和 \(\displaystyle \sum_{l=1}^{r}[ s_{r,i}\oplus s_{l,i} =1]\times (l-1)\)​ 都可以预处理。

void solve()
{
// #define tests
    int n; std::cin >> n;
    std::vector<int> a(n); for (auto& x : a) {std::cin >> x;}
    PrefixXor<i64> pre_xor(a);
    
    std::vector cnt(2, std::vector<Z>(31));
    auto sum(cnt);//维护该数之前该位上为0/1的个数
    cnt[0].assign(31, 1);//一开始0的个数赋成1
    Z ans = 0;
    for (int r = 1; r <= n; r++) {//固定r,更新答案
        for (int j = 30; j >= 0; j--) {
            int x = (pre_xor(r) >> j & 1);
            ans += (cnt[x ^ 1][j] * r - sum[x ^ 1][j]) * (1 << j);//找当前位相反的数码的数量,只用这样才能产生贡献,即异或和为 1
            sum[x][j] += r; cnt[x][j] += 1;
        }
    }
    std::cout << ans << '\n';
}

标签:std,cnt,CF1879D,32,sum,times,区间,思路,oplus
From: https://www.cnblogs.com/kdlyh/p/18249434

相关文章

  • DVR系统设计的大致思路和模块划分
    DVR系统设计的大致思路和模块划分1.源由2.设计步骤2.1需求分析2.2系统架构设计2.3硬件设计与选择2.4软件开发2.5测试与调试2.6部署与运维2.7持续优化3.模块切割3.1摄像头3.2视频处理单元3.3存储系统3.4网络模块3.5视频编码/解码3.6接口与连接3.7控制与......
  • 【华为OD机试真题】159、星际篮球争霸赛 | 机试真题+思路参考+代码解析(C++、Java、Py
    文章目录一、题目......
  • 【华为OD机试真题】155、计算数组中心位置 | 机试真题+思路参考+代码解析(C++、Java、P
    文章目录一、题目......
  • 牛客小白月赛96(待补思路和F)
    比赛链接:牛客小白月赛96赛时感受    赛时在前面卡的时间有点长,C题没开longlongwa了n发,D题没考虑负数又wa了n发,然后来写E的时候时间就不长了,匆忙写一次交一发。A思路    题解#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+10;#......
  • 在 Microsoft SQL Server 2012 中,修改密码的方法与 SQL Server 2000 相比有所变化,但基
    在MicrosoftSQLServer2012中,修改密码的方法与SQLServer2000相比有所变化,但基本思路是相似的。以下是几种常见的方法:使用SQLServerManagementStudio(SSMS):这仍然是最常见和推荐的方法。通过打开SQLServerManagementStudio,连接到相应的SQLServer实例,然后......
  • 智能指针的思路
    目录前言一、智能指针是什么?二、智能指针代码步骤1.创建一个基本的类,这个类有你想实现的功能2.智能指针类3.整体代码总结前言    在日常的类应用场景中,我们会很多时候涉及到申请内存new关键词和清空内存delete的使用,而我们在很多时候会在申请内存后,忘记......
  • 单例模式思路
    文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言        单例模式是一种常用的设计模式,用于确保一个类只有一个实例,并提供全局访问点。一、单例模式是什么?        单例模式是一种设计模式,用于确保一个类只有一个实例对象,......
  • 代码随想录算法训练营第第37天 | 56. 合并区间 、738.单调递增的数字、968.监控二叉
    合并区间本题也是重叠区间问题,如果昨天三道都吸收的话,本题就容易理解了。https://programmercarl.com/0056.合并区间.html能做出来/***@param{number[][]}intervals*@return{number[][]}*/varmerge=function(intervals){intervals.sort((a,b)=>{......
  • 代码随想录算法训练营第三十七天 | 56.合并区间 738.单调递增的数字
    56.合并区间题目链接文章讲解视频讲解思路:  按左区间排序;  遍历所有区间,如果当前区间的左边界小于等于上一个区间的右边界,则合并区间(新区间的左边界为上一个区间的左边界,新区间的右边界为上一个区间的有边界和当前区间有边界中较大的一个)classSolution{public:......
  • 牛客周赛46(思路待补)
    比赛链接:牛客周赛46赛时感受    本场参加的是内测,多亏了内测群的佬提供的思路,得以AK。    ABC都是简单的签到题,D稍微需要分类一下,EF有点算法知识,E可以使用前缀和+二分搜索过掉,但是听说好像还能使用离散化树状数组等等,F是数学知识,隔板法和求质数、求组合。 ......