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

时间:2022-09-24 10:25:11

点此看题面

大致题意: 求前\(k\)大的区间异或和之和。

可持久化\(Trie\)树

之前做过一些可持久化\(Trie\)树题,结果说到底还是主席树。

终于,碰到一道真·可持久化\(Trie\)树的题目。

其实它的实现与主席树也是类似的。

大致思路

首先,我们统计一遍前缀异或和。

然后,我们根据前缀异或和建一棵可持久化\(Trie\)树。

接下来最核心的来了:

我们先求出以每个点为右端点所能得到的最大异或和,这可以在\(Trie\)树上查询得到(和普通的\(Trie\)树是一样的)。

然后,把这些值连同该右端点全扔入大根堆里。

每次,我们取出堆顶,统计答案后求出以该点为右端点所能得到的次大值,然后重新扔入堆里。如果再取到该右端点,就是次次大值、次次次大值,以此类推。

那么如何求次大值呢?

没关系,反正我们本来就是可持久化\(Trie\)树,直接复制该点的\(Trie\)树并将求出的最大值所对应的数在树上删去即可。

这种方法的复杂度应该是\(O((n+k)log\ Max\ a_i)\),但我写得弱了一点,变成了\(O((2n+k)log\ Max\ a_i)\)。虽然很好改,但我懒得改了。。。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define RU Reg unsigned
#define Con const
#define CI Con int&
#define CU Con unsigned&
#define I inline
#define W while
#define N 500000
#define K 200000
#define mp make_pair
#define fir first
#define sec second
using namespace std;
int n,k,p[N+5];unsigned a[N+5];typedef pair<unsigned,int> Pr;
priority_queue<Pr> q;
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
#undef D
}F;
class PersistentTrie//可持久化Trie树
{
private:
#define SZ ((N<<1)+K+1)
#define Log 33
int tot,Rt[N+5];struct node {int Sz,S[2];}O[SZ*Log+5];
I void upt(int& rt1,RI rt2,CU x,CI t,CI D)//修改
{
if((O[rt1=++tot]=O[rt2]).Sz+=t,!~D) return;//复制节点,更新size
RI d=(x>>D)&1;upt(O[rt1].S[d],O[rt2].S[d],x,t,D-1);//处理子节点
}
I unsigned qry(int& rt,CI x,CI D)//询问与x的最大异或和
{
if(!~D) return 0;RI d=(x>>D)&1;
return O[O[rt].S[d^1]].Sz?qry(O[rt].S[d^1],x,D-1)|(1<<D):qry(O[rt].S[d],x,D-1);//能使这一位为1就必使其为1,否则使其为0
}
public:
I PersistentTrie() {tot=1,Update(0,0,0,1);}
I void Update(CI v1,CI v2,CU x,CI t) {upt(Rt[v1],Rt[v2],x,t,31);}
I unsigned Query(CI v) {RU t=qry(Rt[v],a[v],31);return Update(v,v,a[v]^t,-1),t;}//询问,为避免计算多次贡献将其删去
}P;
int main()
{
RI i;Pr t;Reg long long ans=0;
for(F.read(n,k),i=1;i<=n;++i) F.read(a[p[i]=i]),a[i]^=a[i-1],P.Update(i,i-1,a[i],1);//初始化建树
for(i=1;i<=n;++i) q.push(mp(P.Query(i),i));//询问然后扔入堆中
for(i=1;i<=k;++i) t=q.top(),q.pop(),ans+=t.fir,//取出堆顶,统计答案
--p[t.sec]&&(q.push(mp(P.Query(t.sec),t.sec)),0);//将次大值扔入堆中
return printf("%lld",ans),0;//输出答案
}

【洛谷5283】[十二省联考2019] 异或粽子(可持久化Trie树+堆)的更多相关文章

  1. 洛谷&period;5283&period;&lbrack;十二省联考2019&rsqb;异或粽子&lpar;可持久化Trie 堆&rpar;

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

  2. &lbrack;十二省联考2019&rsqb;异或粽子——可持久化trie树&plus;堆

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

  3. &lbrack;十二省联考2019&rsqb; 异或粽子 - 可持久化Trie&comma;堆

    求 \(n\) 元数列的 \(k\) 个不同的子区间使得各个子区间异或和之和最大. Solution (差点又看错题了) 做个前缀和,于是转化成求序列异或和最大的 \(k\) 个数对 建一棵可持久化 ...

  4. P5283 &lbrack;十二省联考2019&rsqb;异或粽子 可持久化01Trie&plus;线段树

    $ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...

  5. 【BZOJ5495】&lbrack;十二省联考2019&rsqb;异或粽子(主席树,贪心)

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

  6. &lbrack;十二省联考2019&rsqb;异或粽子 01trie

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

  7. 【简】题解 P5283 &lbrack;十二省联考2019&rsqb;异或粽子

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

  8. 洛谷&period;5284&period;&lbrack;十二省联考2019&rsqb;字符串问题&lpar;后缀自动机 拓扑 DP&rpar;

    LOJ BZOJ 洛谷 对这题无话可说,确实比较...裸... 像dls说的拿拓扑和parent树一套就能出出来了... 另外表示BZOJ Rank1 tql... 暴力的话,由每个\(A_i\)向它 ...

  9. 洛谷P5283 &amp&semi; LOJ3048:&lbrack;十二省联考2019&rsqb;异或粽子——题解

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

  10. Luogu P5283 &sol; LOJ3048 【&lbrack;十二省联考2019&rsqb;异或粽子】

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

随机推荐

  1. floyd算法小结

    floyd算法是被大家熟知的最短路算法之一,利用动态规划的思想,f[i][j]记录i到j之间的最短距离,时间复杂度为O(n^3),虽然时间复杂度较高,但是由于可以处理其他相似的问题,有着广泛的应用,这 ...

  2. ElasticSearch 2 &lpar;6&rpar; - 插件安装Head、Kopf与Bigdesk

    ElasticSearch 2 (6) - 插件安装Head.Kopf与Bigdesk 摘要 安装Elasticsearch插件Head.Kopf与Bigdesk 版本 elasticsearch版本 ...

  3. vim--golang代码补全

    我想说,我折腾了很久编辑器,试了九种办法 最后我只成功了一种 但我依然想就我混乱的逻辑做下整理 一.一开始,我试图入手ipad编码软件,大概9美金吧,叫Textastic.我试图用它的近亲来试验Tex ...

  4. Spring&period;Net的Ioc功能基本配置

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入.面向方面编程(AOP).数据访问抽象及ASP.NET扩展等等. Spri ...

  5. Contest1065 - 第四届&OpenCurlyDoubleQuote;图灵杯”NEUQ-ACM程序设计竞赛(个人赛)C粉丝与汉诺塔

    题目描述 苟利国家生死以,岂因福祸避趋之?作为ACM真正的粉丝,应该都听闻过汉诺塔问题,汉诺塔问题是这样的: 有三根柱子,编号A,B,C柱,初始情况下A柱上有n个盘子,小盘子在上大盘子在下,n个盘子大 ...

  6. EF Code First 学习笔记:表映射

    多个实体映射到一张表 Code First允许将多个实体映射到同一张表上,实体必须遵循如下规则: 实体必须是一对一关系 实体必须共享一个公共键 观察下面两个实体: public class Perso ...

  7. maya和Unity中的坐标系旋转

    maya软件是用的右手坐标系,默认旋转顺序是ZYX,即先绕Z轴旋转,再绕Y轴旋转,最后绕X轴旋转. 比如在maya软件中,右侧的旋转顺序是可选的,默认的选择是“XYZ”,其实物体旋转顺序是倒着念,即上 ...

  8. Hadoop Hive与Hbase整合&plus;thrift

    Hadoop Hive与Hbase整合+thrift 1.  简介 Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句 ...

  9. 【高性能】生成唯一时间戳ID,1毫秒预计能生成1000个

    凡事涉及到高性能貌似都是高大上的东西,所以嘛我也试试:其实这个时间戳ID的生成主要为了解决我们公司内部的券号生成,估计有小伙伴认为券号生成有这么麻烦嘛,搞个自增ID完全可以用起来,或者时间取毫微米时间 ...

  10. 制作windows镜像

    下载包含windows驱动的iso: http://222.186.58.77/virtio-win-0.1-30.iso?fid=kF46uzxlPMrgvLDErP0ohhZYwAUASLoCAA ...