[LOJ3048] [十二省联考2019] 异或粽子
题目链接
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] 异或粽子的更多相关文章
- [十二省联考2019]异或粽子——可持久化trie树+堆
题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...
- 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)
[BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...
- [十二省联考2019]异或粽子 01trie
[十二省联考2019]异或粽子 01trie 链接 luogu 思路 首先求前k大的(xo[i]^xo[j])(i<j). 考场上只想到01trie,不怎么会写可持久,就写了n个01trie,和 ...
- 【简】题解 P5283 [十二省联考2019]异或粽子
传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...
- Luogu P5283 / LOJ3048 【[十二省联考2019]异或粽子】
联考Day1T1...一个考场上蠢了只想到\(O(n^2)\)复杂度的数据结构题 题目大意: 求前\(k\)大区间异或和的和 题目思路: 真的就是个sb数据结构题,可持久化01Trie能过(开O2). ...
- 洛谷P5283 & LOJ3048:[十二省联考2019]异或粽子——题解
https://www.luogu.org/problemnew/show/P5283 https://loj.ac/problem/3048 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子 ...
- Luogu P5283 [十二省联考2019]异或粽子
感觉不是很难的一题,想了0.5h左右(思路歪了,不过想了一个大常数的两只\(\log\)做法233) 然后码+调了1h,除了一个SB的数组开小外基本上也没什么坑点 先讲一个先想到的方法,我们对于这种问 ...
- [十二省联考2019]异或粽子(堆+可持久化Trie)
前置芝士:可持久化Trie & 堆 类似于超级钢琴,我们用堆维护一个四元组\((st, l, r, pos)\)表示以\(st\)为起点,终点在\([l, r]\)内,里面的最大值的位置为\( ...
- Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)
做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两 ...
随机推荐
- Educational Codeforces Round 67
Educational Codeforces Round 67 CF1187B Letters Shop 二分 https://codeforces.com/contest/1187/submissi ...
- 洛谷P1076 寻宝
寻宝 模拟加优化,细节比较重要. 我们用ti[i]表示i这一层有楼梯的个数,然后我们把当前1号点的数据mod上ti[i],然后使该数不能等于0,就行了. #include <bits/stdc+ ...
- Koa 脚手架创建项目
Koa 脚手架创建项目 通过应用 koa 脚手架生成工具 可以快速创建一个基于 koa2 的应用的骨架 全局安装koa npm install koa-generator -g //必须安装到全局 创 ...
- hotspot编译
"AA=="1",==", /usr/bin/make -s VERBOSE="-s" LOG_LEVEL="warn" ...
- #C++初学记录(动态规划 被3整除的子序列)
原题:牛客网 动态规划dynamic programming 的入门级题目 题目描述 : 给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除 答案对1e9+7取模 输入描述: 输入一 ...
- [BUAA软工]Alpha阶段事后分析
设想和目标 虽然我们是从零开始的一个自定义项目,但语音Coding助手从一开始的设计与目标就很明确:加入语音接口使其能在shell端实现命令语音实现以及编辑运行脚本,设计前端编辑器并将后端shell与 ...
- 定制比特币btc地址address
https://99bitcoins.com/how-to-get-a-custom-bitcoin-address/ https://en.bitcoin.it/wiki/Vanitygen htt ...
- Linux下emacs如何安装
ftp://ftp.gnu.org/gnu/emacs/ 下载对应版本编译安装 cd 自己想安装的目录 sudo wget ftp://ftp.gnu.org/gnu/emacs/emacs-24.4 ...
- mysql全文索引:fulltext
fulltext全文索引 要使用全文索引,不仅需要把某个字段的索引类型设置为fulltext,还需要修改mysql配置文件: [mysqld] ft_wordlist_charset #表示词典的字符 ...
- dockerfile运行mysql并初始化数据
本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动MySQL服务接受外部连接,主要是通过Dockerfile和 ...