感觉不是很难的一题,想了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]异或粽子的更多相关文章

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

    原题传送门 看见一段的异或和不难想到要做异或前缀和\(s\) 我们便将问题转化成:给定\(n\)个数,求异或值最靠前的\(k\)对之和 我们珂以建一个可持久化01trie,这样我们就珂以求出每个值\( ...

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

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

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

    考场上想到了没打完,细节思路还是不是很优,我原先的想法是每一次找完后标记那个点,下次再继续找(并不是这个意思,说不清楚)但实际上和平衡树一样加个大小就很好写了 #include<bits/std ...

  4. P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Flask python初期九九乘法表

    from  flask import Flask    #导入 app = Flask(__name__) @app.route('/') def index(): res=" " ...

  2. [区块链] 加密算法——Hash算法(进阶)

    为了为保证存储于区块链中的信息的安全与完整,区块链中使用了包含密码哈希函数和椭圆曲线公钥密码技术在内的大量的现代密码学技术,同时,这些密码学技术也被用于设计基于工作量证明的共识算法并识别用户. 在前边 ...

  3. ViewPagerWithImageDemo【ViewPager如何判断滑动到第一页和最后一页以及弹出对话框功能】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录viewpager滑动的时候弹出对话框的功能(关键功能是滑动弹出对话框后,隐藏对话框的时候当前页可以还原到原位置),顺便判断首页 ...

  4. Angular动态创建组件之Portals

    这篇文章主要介绍使用Angular api 和 CDK Portals两种方式实现动态创建组件,另外还会讲一些跟它相关的知识点,如:Angular多级依赖注入.ViewContainerRef,Por ...

  5. 声明式RESTful客户端在asp.net core中的应用

    1 声明式RESTful客户端 声明式服务调用的客户端,常见有安卓的Retrofit.SpringCloud的Feign等,.net有Refit和WebApiClient,这些客户端都是以java或. ...

  6. FastDFS分布式文件系统&Nginx负载均衡最小环境安装配置[超级详解]

    1.背景 FastDFS 是一款开源的.分布式文件系统(Distributed File System),由淘宝开发平台部资深架构师余庆开发.该开源项目的主页是 http://code.google. ...

  7. HTTP1.0和HTTP1.1的区别

    1.HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理 HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器 ...

  8. TensorFlow tutorial

    代码示例来自https://github.com/aymericdamien/TensorFlow-Examples tensorflow先定义运算图,在run的时候才会进行真正的运算. run之前需 ...

  9. C# NuGet包管理命令

    NuGet Package Manager Console 内置于 Visual Studio 在 Windows 2012 和更高版本. (不包含在 Visual Studio 用于 Mac 或 V ...

  10. Yii2设计模式——设计模式简介

    我们首先来思考一个问题:作为工程师,我们的价值是什么? 笔者认为是--解决用户问题. 我们的任何知识和技能,如果不能解决特定的问题,那么就是无用的屠龙之术:我们的任何经验,如果不能对解决新的问题有用, ...