Luogu P5283 [十二省联考2019]异或粽子
感觉不是很难的一题,想了0.5h左右(思路歪了,不过想了一个大常数的两只\(\log\)做法233)
然后码+调了1h,除了一个SB的数组开小外基本上也没什么坑点
先讲一个先想到的方法,我们对于这种问题显然可以二分第\(k\)大,然后验证有多少个值小于等于它
然后考虑怎么判断,我们建一棵0/1Trie,然后枚举一个右端点,每次把整个Trie异或上这个点的权值
具体实现的话就是不断向下走的过程,当这一位为\(1\)时交换左右子树即可
然后相当于查小于等于一个数的数个数以及和,直接Trie上节点维护一下即可
这样是\(n \log \max{a_i}\log n\)的,由于\(a_i\)值域比较大而且直接跑满了,因此可能无法通过此题
然后慢慢就想到一种诡异的做法,先记录一下前缀异或和,然后考虑算出每个点为右端点时的最大值和左端点
这样有一个好处,我们每次用堆维护这\(n\)的点为右端点是答案的最大值,那么直接算出前\(k\)大即可
那么考虑如何计算,首先如果不考虑删除的话是挺简单的,我们建一棵可持久化0/1Trie,然后每个点在对应的Trie上找一个数和它异或值最大即可(类似于普通0/1Trie)
那么问题来了,我们统计完一个点的值时怎么删除能,可持久化数据结构一旦删除不是就全乱了么
其实不一定,由于这里只删一条已添加过的链,因此有一种奇妙的方法
我们记录左端点后找到右端点此时的Trie根节点编号,然后新开一个可持久化0/1Trie,然后直接在此时的版本上删去左端点对应的链即可
由于堆只需要取\(k\)次值,因此最多多产生\(k\)个版本,所以这部分的复杂度为\((n+k)\log \max{a_i}\)
然后加上堆的\(k\log n\)之后还是轻松通过此题,不过注意版本的数组大小要开大
CODE
#include<cstdio>
#include<cctype>
#include<queue>
#define RI register int
#define CI const int&
#define Tp template <typename T>
using namespace std;
typedef unsigned int u32;
const int N=5e5+5,R=32;
struct data
{
u32 val; int id;
inline data(const u32& Val=0,CI Id=0)
{
val=Val; id=Id;
}
friend inline bool operator < (const data& A,const data& B)
{
return A.val<B.val;
}
}; priority_queue <data> hp; long long ans;
int n,k,rt[N<<1],pos[N],cur; u32 a[N],pfx[N],ret;
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
char Fin[S],*A,*B;
public:
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
#undef tc
}F;
class Segment_Tree
{
private:
struct segment
{
int ch[2],size;
}node[N*(R+1)<<1]; int tot;
public:
#define lc(x) node[x].ch[0]
#define rc(x) node[x].ch[1]
#define S(x) node[x].size
inline void build(int& now,CI dep=R-1)
{
now=++tot; S(now)=1; if (!~dep) return; build(lc(now),dep-1);
}
inline void insert(CI lst,int& now,const u32& num,CI mv,CI dep=R-1)
{
now=++tot; node[now]=node[lst]; S(now)+=mv; if (!~dep) return;
if ((num>>dep)&1u) insert(rc(lst),rc(now),num,mv,dep-1);
else insert(lc(lst),lc(now),num,mv,dep-1);
}
inline void query(CI now,const u32& num,CI dep=R-1)
{
if (!~dep) return; if (S(node[now].ch[((num>>dep)&1)^1]))
ret|=1u<<dep,query(node[now].ch[((num>>dep)&1)^1],num,dep-1);
else query(node[now].ch[(num>>dep)&1],num,dep-1);
}
#undef lc
#undef rc
#undef S
}SEG;
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (F.read(n),F.read(k),i=1;i<=n;++i) F.read(a[i]);
for (SEG.build(rt[0]),i=1;i<=n;++i)
{
pfx[i]=pfx[i-1]^a[i]; SEG.insert(rt[i-1],rt[i],pfx[i],1);
ret=0; SEG.query(rt[pos[i]=i],pfx[i]); hp.push(data(ret,i));
}
for (cur=n;k;--k)
{
data nw=hp.top(); hp.pop(); ans+=nw.val;
SEG.insert(rt[pos[nw.id]],rt[++cur],nw.val^pfx[nw.id],-1);
ret=0; SEG.query(rt[pos[nw.id]=cur],pfx[nw.id]); hp.push(data(ret,nw.id));
}
return printf("%lld",ans),0;
}
Luogu P5283 [十二省联考2019]异或粽子的更多相关文章
- 【题解】Luogu P5283 [十二省联考2019]异或粽子
原题传送门 看见一段的异或和不难想到要做异或前缀和\(s\) 我们便将问题转化成:给定\(n\)个数,求异或值最靠前的\(k\)对之和 我们珂以建一个可持久化01trie,这样我们就珂以求出每个值\( ...
- 【简】题解 P5283 [十二省联考2019]异或粽子
传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...
- P5283 [十二省联考2019]异或粽子
考场上想到了没打完,细节思路还是不是很优,我原先的想法是每一次找完后标记那个点,下次再继续找(并不是这个意思,说不清楚)但实际上和平衡树一样加个大小就很好写了 #include<bits/std ...
- P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树
$ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...
- [十二省联考2019]异或粽子 01trie
[十二省联考2019]异或粽子 01trie 链接 luogu 思路 首先求前k大的(xo[i]^xo[j])(i<j). 考场上只想到01trie,不怎么会写可持久,就写了n个01trie,和 ...
- [十二省联考2019]异或粽子——可持久化trie树+堆
题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...
- 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)
[BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...
- 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 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子 ...
随机推荐
- kubernetes 安装备注
一.安装环境 阿里云:centos 7.3 master节点:外网IP(116.62.205.90).内网IP(172.16.223.200) node节点:外网IP(116.62.212.174). ...
- iOS可视化动态绘制连通图(Swift版)
上篇博客<iOS可视化动态绘制八种排序过程>可视化了一下一些排序的过程,本篇博客就来聊聊图的东西.在之前的博客中详细的讲过图的相关内容,比如<图的物理存储结构与深搜.广搜>.当 ...
- Java三种方式实现栈和队列
栈:LIFO(后进先出) 队列:FIFO(先进先出) 1.栈:LIFO(后进先出) 1.1.栈的顺序存储结构实现: /** * 基于数组实现的顺序栈 * @param <E> */ pub ...
- shell if条件判断中:双中括号与单中括号的区别
电脑重装了系统,登录虚拟机的shell脚本需重写,在为编写的脚本命名时发现存在同名脚本,才想起来是连接公司服务器的登录脚本,不想写俩脚本,怕记混了,那就整合一下.代码如下: #!/bin/bash#z ...
- Jenkins高级用法 - Jenkinsfile 介绍及实战经验
系列目录 1.Jenkins 安装 2.Jenkins 集群 3.Jenkins 持续集成 - ASP.NET Core 持续集成(Docker&自由风格&Jenkinsfile) 4 ...
- 记录DEV gridview获取行列数据方法
DataRow dr = this.gridView1.GetDataRow(this.gridView1.FocusedRowHandle);//获取选中行 string str = gridVie ...
- Asp.Net Core WebApi中接入Swagger组件(初级)
开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...
- C++ 编译期封装-Pimpl技术
Pimpl技术——编译期封装 Pimpl 意思为“具体实现的指针”(Pointer to Implementation), 它通过一个私有的成员指针,将指针所指向的类的内部实现数据进行隐藏, 是隐藏实 ...
- 微信公众号开发C#系列-8、自定义菜单及菜单响应事件的处理
1.概述 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能.菜单分为默认菜单与个性化菜单.个性化菜单接口是为了帮助公众号实现灵活的业务运营,开发者可以通过该接口,让公众号的不同用户群 ...
- 【Vue.js】代码优化:在dom中加一行v-if就可少写一个循环类方法
[问题描述] 把当前用户的购物车中(cartList),商品(good)选中字段checked = true的商品在订单页面中进行展示出来. [一般做法](两次循环) 首先取出当前用户的购物车列表,循 ...