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

https://loj.ac/problem/3048

小粽是一个喜欢吃粽子的好孩子。今天她在家里自己做起了粽子。

小粽面前有 n 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 1 到 n。第 ii 种馅儿具有一个非负整数的属性值 a_i。每种馅儿的数量都足够多,即小粽不会因为缺少原料而做不出想要的粽子。小粽准备用这些馅儿来做出 k 个粽子。

小粽的做法是:选两个整数数 l, r,满足 1⩽l⩽r⩽n,将编号在 [l,r] 范围内的所有馅儿混合做成一个粽子,所得的粽子的美味度为这些粽子的属性值的异或和。(异或就是我们常说的 xor 运算,即 C/C++ 中的 ˆ 运算符或 Pascal 中的 xor 运算符)

小粽想品尝不同口味的粽子,因此它不希望用同样的馅儿的集合做出一个以上的 粽子。

小粽希望她做出的所有粽子的美味度之和最大。请你帮她求出这个值吧!

UPD:手痒了于是还是把代码写了……

不要在意我只是突然诈了一个尸。

以及场外选手题解口胡之后看了一下正解发现差不多?

正好一直想要诈一个尸,就用这个诈一个尸吧。

顺(主)便(要)聊聊心路历程。

——————

看到异或取最大第一眼想到线性基,然后看到连续的数就想到了BZOJ3261:最大异或和 。(天哪我记性真好一年前的东西我还记得)

然而此时并看不出二者的关系。

然后想暴力,枚举$O(n^2)$,但$k$与$n$并非一个数量级的。

于是想到了BZOJ2006:[NOI2010]超级钢琴 对前$k$大值的处理方法。(天哪我记性真好一年前的东西我还记得*2)

而超级钢琴那道题我们是用了st表维护的,但是异或显然不能用st表维护。

那就可持久化trie呗!顺理成章的联系到了一起。

于是题解如下:首先预处理前缀异或和$s$,建立可持久化trie,则原$[l,r]$的异或和即为$s[r] \; xor \; s[l-1]$。

于是固定$l$求$r$使得$s[r] \; xor \; s[l-1]$尽可能的最大(设为$w$吧),然后将这些信息一起扔到堆里面(同时我们把$r$所在的范围$L,R$一起扔里面)。

每次弹出一个$(l,r,w,L,R)$的时候,我们就要找第二大的$[l,r]$扔进去,超级钢琴告诉我们,第二大的$r$一定在$[L,r-1]$和$[r+1,R]$当中,我们干脆把区间分成两份各求一遍直接都扔进去就好了。

复杂度一个建trie$O(nloga_i)$一个预处理$O(nloga_i)$一个弹$O(kloga_i)$。

(老年选手不会算复杂度了不知道对不对orz)

另外洛谷需要开O2

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long ll;
const int N=5e5+;
const int B=;
inline ll read(){
ll X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int son[],sum,num;
}tr[*N];
int tot,rt[N],pool;
ll s[N];
void insert(int y,int &x,ll k,int pos,int now){
tr[x=++pool]=tr[y];tr[x].sum++;
if(now<){tr[x].num=pos;return;}
bool p=k&(1LL<<now);
insert(tr[y].son[p],tr[x].son[p],k,pos,now-);
return;
}
int query(int nl,int nr,ll k,int now){
if(now<)return tr[nr].num;
bool p=k&(1LL<<now);
int delta=tr[tr[nr].son[p^]].sum-tr[tr[nl].son[p^]].sum;
if(delta>)return query(tr[nl].son[p^],tr[nr].son[p^],k,now-);
else return query(tr[nl].son[p],tr[nr].son[p],k,now-);
}
struct data{
int l,r;
ll w;
int L,R;
bool operator <(data b)const{
return w<b.w;
}
};
priority_queue<data>q;
int main(){
int n=read(),k=read();
for(int i=;i<=n;i++)s[i]=s[i-]^read();
for(int i=;i<=n;i++)insert(rt[i-],rt[i],s[i],i,B);
for(int i=;i<=n;i++){
int l=i;int r=query(rt[l-],rt[n],s[l-],B);
q.push((data){l,r,s[r]^s[l-],l,n});
}
ll ans=;
while(k--){
data tmp=q.top();q.pop();
ans+=tmp.w;
int i=tmp.l,j=tmp.r;
if(tmp.L<=j-){
int t=query(rt[tmp.L-],rt[j-],s[i-],B);
q.push((data){i,t,s[t]^s[i-],tmp.L,j-});
}
if(j+<=tmp.R){
int t=query(rt[j],rt[tmp.R],s[i-],B);
q.push((data){i,t,s[t]^s[i-],j+,tmp.R});
}
}
printf("%lld\n",ans);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

洛谷P5283 & LOJ3048:[十二省联考2019]异或粽子——题解的更多相关文章

  1. 【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)

    点此看题面 大致题意: 求前\(k\)大的区间异或和之和. 可持久化\(Trie\)树 之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树. 终于,碰到一道真·可持久化\(Trie\)树的 ...

  2. [LOJ3048] [十二省联考2019] 异或粽子

    题目链接 LOJ:https://loj.ac/problem/3048 洛谷:https://www.luogu.org/problemnew/show/P5283 Solution 考虑每个子串都 ...

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

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

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

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

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

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

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

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

  7. 洛谷.5283.[十二省联考2019]异或粽子(可持久化Trie 堆)

    LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找 ...

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

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

  9. LOJ 3049: 洛谷 P5284: 「十二省联考 2019」字符串问题

    题目传送门:LOJ #3049. 题意简述: 给定一个长度为 \(n\) 的母串 \(S\). 有 \(n_a\) 个 A 类串,都是 \(S\) 的子串,以区间的形式给出. 有 \(n_b\) 个 ...

随机推荐

  1. RAID卡的结构详解

    软件RAID的缺点如此之多,使人们不断地思考更多实现RAID的方法.既然软件缺点太多,那么用硬件实现如何呢? RAID卡就是一种利用独立硬件来实现RAID功能的方法.要在硬件上实现RAID功能,必须找 ...

  2. 如何通过阿里云APP进行域名备案?阿里云备案流程需要多久?

    如何通过阿里云APP进行域名备案? 1.准备备案材料(很多初次使用阿里云APP进行备案的同学会问备案需要准备哪些资料,不二版本下面就给大家一一列举出来) 个人备案需要材料: ⑴<用户网站备案授权 ...

  3. mysql实现oracle sequence方案

    转自: http://blog.csdn.net/javaGirlOne/article/details/47256183 背景:先总结一下MYSQL 自增长与ORACLE 序列的区别: 自增长只能用 ...

  4. Redis学习(一):CentOS下redis安装和部署

    1.基础知识  redis是用C语言开发的一个开源的高性能键值对(key-value)数据库.它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止redis支持的键值数据类型如下字符串.列表 ...

  5. dobule运算

    DecimalFormat df = new DecimalFormat("0.00"); double rate = (warnMonNum/totalCustCount)*10 ...

  6. 关于‘1001.A+B Format (20)’的解题报告

    1001.A+B Format(20) 首先要感谢一下指导我github上传问题的小伙伴们,捣腾了一整天我终于摸到了一点门路,真的谢谢你们. 小豪的github 问题描述: Calculate a + ...

  7. week4f:个人博客作业

    8,工作中的照片 9,对方编程习惯总结 宋成鑫(以后简称老宋).老宋,对编程的思想看的比较重,具体什么是编程的思想,我是也不是很清楚.但是,在编程过程中,老宋的一些话给了我启示.这或许就是编程的思想吧 ...

  8. [建树(非二叉树)] 1090. Highest Price in Supply Chain (25)

    1090. Highest Price in Supply Chain (25) A supply chain is a network of retailers(零售商), distributors ...

  9. Akka系列---什么是Actor

    本文已.Net语法为主,同时写有Scala及Java实现代码 严肃的说,演员是一个广泛的概念,作为外行人我对Actor 模型的定义: Actor是一个系统中参与者的虚拟人物,Actor与Actor之间 ...

  10. C++派生类构造函数调用顺序(详解)

    我们来看下面一段代码: class B1 { public: B1(int i) {cout<<"constructing B1 "<<i<<e ...