题目链接

LOJ:https://loj.ac/problem/3048

洛谷:https://www.luogu.org/problemnew/show/P5283

Solution

考虑每个子串都是一个前缀的后缀,我们可以用堆维护四元组\((l,r,ed,pos)\)表示当前右端点为\(ed\),左端点范围是\([l,r]\),其中\([pos+1,ed]\)这个区间的异或和最大。

这其实就是固定了前缀来找后缀。那么我们每次可以从堆顶拿一个四元组出来,然后分裂成两个:\((l,pos-1,ed,\cdots),(pos+1,r,ed,\cdots)\),顺便更新答案。其中省略号的部分可以通过可持久化\(\rm 01trie\)树算出来。

复杂度\(O(n\log n+k\log n)\)。

#include<bits/stdc++.h>
using namespace std; #define int unsigned int template <class T> void read(T &x) {
x=0;T f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
} template <class T> void print(T x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
template <class T> void write(T x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double
#define ll long long #define pii pair<int,int >
#define vec vector<int > #define pb push_back
#define mp make_pair
#define fr first
#define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 5e5+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;
const int maxm = 2e7+10; int a[maxn],n,k; struct trie {
int son[maxm][2],tot,cnt[maxm],id[maxm],rt[maxn]; void ins(int r,int x) {
rt[r]=++tot;int now=rt[r],pre;if(r) pre=rt[r-1];else pre=0;
for(int i=31;~i;i--) {
int t=x>>i&1;
son[now][t^1]=son[pre][t^1];
now=(son[now][t]=++tot);
pre=son[pre][t];cnt[now]=cnt[pre]+1;
}id[now]=r;
} int query(int l,int r,int x) {
int now=rt[r],pre=0;if(l) pre=rt[l-1];
for(int i=31;~i;i--) {
int t=!(x>>i&1);
if(cnt[son[now][t]]-cnt[son[pre][t]]==0) t^=1;
now=son[now][t],pre=son[pre][t];
}return id[now];
}
}T; struct data {
int l,r,ed,pos; data () {} data (int _l,int _r,int _ed) {
l=_l,r=_r,ed=_ed;
pos=T.query(l,r,a[ed]);
} bool operator < (const data &rhs) const {
return (a[ed]^a[pos])<(a[rhs.ed]^a[rhs.pos]);
}
}; priority_queue<data > s; signed main() {
read(n),read(k);T.ins(0,0);
for(int i=1;i<=n;i++) read(a[i]),a[i]^=a[i-1],T.ins(i,a[i]);
for(int i=1;i<=n;i++) s.push(data(0,i-1,i));
ll ans=0;
for(int i=1;i<=k;i++) {
if(s.empty()) break;
data x=s.top();s.pop();
ans+=a[x.ed]^a[x.pos];
if(1ll*x.pos-1>=1ll*x.l) s.push(data(x.l,x.pos-1,x.ed));
if(x.r>=x.pos+1) s.push(data(x.pos+1,x.r,x.ed));
}write(ans);
return 0;
}

[LOJ3048] [十二省联考2019] 异或粽子的更多相关文章

  1. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  2. 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)

    [BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...

  3. [十二省联考2019]异或粽子 01trie

    [十二省联考2019]异或粽子 01trie 链接 luogu 思路 首先求前k大的(xo[i]^xo[j])(i<j). 考场上只想到01trie,不怎么会写可持久,就写了n个01trie,和 ...

  4. 【简】题解 P5283 [十二省联考2019]异或粽子

    传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...

  5. Luogu P5283 / LOJ3048 【[十二省联考2019]异或粽子】

    联考Day1T1...一个考场上蠢了只想到\(O(n^2)\)复杂度的数据结构题 题目大意: 求前\(k\)大区间异或和的和 题目思路: 真的就是个sb数据结构题,可持久化01Trie能过(开O2). ...

  6. 洛谷P5283 & LOJ3048:[十二省联考2019]异或粽子——题解

    https://www.luogu.org/problemnew/show/P5283 https://loj.ac/problem/3048 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子 ...

  7. Luogu P5283 [十二省联考2019]异或粽子

    感觉不是很难的一题,想了0.5h左右(思路歪了,不过想了一个大常数的两只\(\log\)做法233) 然后码+调了1h,除了一个SB的数组开小外基本上也没什么坑点 先讲一个先想到的方法,我们对于这种问 ...

  8. [十二省联考2019]异或粽子(堆+可持久化Trie)

    前置芝士:可持久化Trie & 堆 类似于超级钢琴,我们用堆维护一个四元组\((st, l, r, pos)\)表示以\(st\)为起点,终点在\([l, r]\)内,里面的最大值的位置为\( ...

  9. Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)

    做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两 ...

随机推荐

  1. 洛谷 P2312 解方程 题解

    P2312 解方程 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 [1,m][1,m] 内的整数解(\(n\) 和 \(m\) 均为 ...

  2. HTML5之图片在Retina屏的常用几种处理方式

    Media Queries使用css3的媒体查询实现高清屏的图片处理. @media only screen and (-webkit-min-device-pixel-ratio: 1.5), on ...

  3. python学习笔记一: 《python3 input()函数》

    一.在学习之前需要先了解: 1.Python3.x 中 input() 函数接受一个标准输入数据,返回为 string 类型,即把任何输入看作str. 2.input可以用作文本输入,如用户名,密码框 ...

  4. 排序---希尔排序Java

    希尔排序 插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减 ...

  5. [300iq contest1-J]Jealous Split

    题意 有一个非负整数序列\({a_i}\),你要将他分成恰好\(k\)段,记\(s_i\)为第\(i\)段的和,\(m_i\)为第\(i\)段的最大值,你需要保证这种划分方案对任意\(1 \le i ...

  6. Linux 权限规划ACL

    什么是ACL ACL是Access Control List的缩写,主要目的是提供传统的owner.group.others的read.write.execute权限之外的具体权限设置 ACL可以针对 ...

  7. Gradle入门系列

    http://blog.jobbole.com/71999/ 版权声明:本文为博主原创文章,未经博主允许不得转载.

  8. Java8新特性 (一)Lambda

    目录 一.Lambda介绍 二.Lambda用法实例 三.Lambda变量作用域 前言: 这两天彻底的复习了一遍Java8的各种新特性,趁着热乎劲,把知识点整理成博客的形式保存一下. 一.Lambda ...

  9. 2019_软工实践_Beta(5/5)

    队名:955 组长博客:点这里! 作业博客:点这里! 组员情况 组员1(组长):庄锡荣 过去两天完成了哪些任务 文字/口头描述 部署新服务器 展示GitHub当日代码/文档签入记录 接下来的计划 准备 ...

  10. ubuntu16.04 安装使用meld及问题

    本文链接:https://blog.csdn.net/ai_liuliu/article/details/95504095安装meldsudo apt-get install meld启动meld方法 ...