做前缀异或和,用堆维护一个五元组(x,l,r,p,v),x为区间右端点的值,l~r为区间左端点的范围,p为x在l~r中最大异或和的位置,v为该最大异或和,每次从堆中取出v最大的元素,以p为界将其切成两部分重新扔进堆即可。查询一个值在一个区间中的最大异或和用可持久化trie实现。luogu上T掉了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define N 500010
#define ui unsigned int
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
ui read()
{
ui x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
int n,k,goat,root[N],cnt;
const ui I=1;
ui a[N];
struct data{int ch[2],s,id;
}trie[N*33];
void ins(int &k,ui x,int i,int ID)
{
trie[++cnt]=trie[k];k=cnt;
trie[k].s++;trie[k].id=ID;
if (i<0) return;
ins(trie[k].ch[(x&(I<<i))>0],x,i-1,ID);
}
struct data2
{
ui x;int l,r,p;ui d;
bool operator <(const data2&a) const
{
return d<a.d;
}
};
priority_queue<data2> q;
int query(int l,int r,ui x)
{
for (int i=31;~i;i--)
{
int op=(x&(I<<i))>0;
if (trie[trie[r].ch[op^1]].s>trie[trie[l].ch[op^1]].s) l=trie[l].ch[op^1],r=trie[r].ch[op^1];
else l=trie[l].ch[op],r=trie[r].ch[op];
}
return trie[r].id;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
cin>>n>>k;ins(root[0],0,31,0);
for (int i=1;i<=n;i++)
{
root[i]=root[i-1];
a[i]=a[i-1]^read();
ins(root[i],a[i],31,i);
}
root[-1]=0;
for (int i=1;i<=n;i++)
{
int p=query(root[-1],root[i-1],a[i]);
q.push((data2){a[i],0,i-1,p,a[i]^a[p]});
}
ll ans=0;
while (k--)
{
data2 t=q.top();q.pop();ans+=t.d;int x=t.p;
if (x>t.l)
{
int p=query(root[t.l-1],root[x-1],t.x);
q.push((data2){t.x,t.l,x-1,p,t.x^a[p]});
}
if (x<t.r)
{
int p=query(root[x],root[t.r],t.x);
q.push((data2){t.x,x+1,t.r,p,t.x^a[p]});
}
}
cout<<ans;
return 0;
}

  场上写的是CF1055F的做法(当然没有隐式建trie了)。考场代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 500010
#define uint unsigned int
#define mp(x,y) make_pair((x),(y))
uint read()
{
uint x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+(c^48),c=getchar();
return x;
}
typedef pair<int,int> pii;
typedef pair<uint,int> pui;
int n,k,trie[N*33][2],size[N*33],nxt[N*33],head[N*33],T,cnt;
pii p[N*4],q[N*4];
uint val[N*33],a[N],v[N*33];
pui b[N*4];
ll ans;
void ins(uint x)
{
int k=0;uint I=1;
for (int i=31;~i;i--)
{
if (!trie[k][(x&(I<<i))>0]) trie[k][(x&(I<<i))>0]=++cnt;
k=trie[k][(x&(I<<i))>0];size[k]++;
v[++T]=x;nxt[T]=head[k];head[k]=T;
}
val[k]=x;
}
bool cmp(pui a,pui b)
{
return a.first>b.first;
}
int main()
{
freopen("xor.in","r",stdin);
freopen("xor.out","w",stdout);
n=read(),k=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) a[i]^=a[i-1];
for (int i=0;i<=n;i++) ins(a[i]);
cnt=1;p[1]=mp(0,0);
for (int _=32;_;_--)
{
ll tot=0;
for (int i=1;i<=cnt;i++)
{
tot+=1ll*size[trie[p[i].first][0]]*size[trie[p[i].second][1]];
if (p[i].first!=p[i].second) tot+=1ll*size[trie[p[i].first][1]]*size[trie[p[i].second][0]];
}
if (tot>k)
{
int u=0;
for (int i=1;i<=cnt;i++)
{
if (p[i].first!=p[i].second&&(trie[p[i].first][0]>0&&trie[p[i].second][1]>0))
{
q[++u].first=trie[p[i].first][0];
q[u].second=trie[p[i].second][1];
}
if (trie[p[i].first][1]>0&&trie[p[i].second][0]>0)
{
q[++u].first=trie[p[i].first][1];
q[u].second=trie[p[i].second][0];
}
}
cnt=u;for (int i=1;i<=cnt;i++) p[i]=q[i];
}
else
{
k-=tot;
for (int i=1;i<=cnt;i++)
{
int L=trie[p[i].first][0],R=trie[p[i].second][1];
for (int x=head[L];x;x=nxt[x])
for (int y=head[R];y;y=nxt[y])
ans+=v[x]^v[y];
if (p[i].first!=p[i].second)
{
int L=trie[p[i].first][1],R=trie[p[i].second][0];
for (int x=head[L];x;x=nxt[x])
for (int y=head[R];y;y=nxt[y])
ans+=v[x]^v[y];
}
}
int u=0;
for (int i=1;i<=cnt;i++)
{
if (trie[p[i].first][0]>0&&trie[p[i].second][0]>0)
{
q[++u].first=trie[p[i].first][0];
q[u].second=trie[p[i].second][0];
}
if (trie[p[i].first][1]>0&&trie[p[i].second][1]>0)
{
q[++u].first=trie[p[i].first][1];
q[u].second=trie[p[i].second][1];
}
}
cnt=u;for (int i=1;i<=cnt;i++) p[i]=q[i];
}
}
for (int i=1;i<=cnt;i++)
{
b[i].first=val[p[i].first]^val[p[i].second];
if (1ll*size[p[i].first]*size[p[i].second]>k) b[i].second=k;
else b[i].second=size[p[i].first]*size[p[i].second];
}
sort(b+1,b+cnt+1,cmp);
for (int i=1;i<=cnt;i++)
if (k>b[i].second) ans+=1ll*b[i].first*b[i].second,k-=b[i].second;
else {ans+=1ll*b[i].first*k;break;}
cout<<ans;
return 0;
}

  

Luogu5283 十二省联考2019异或粽子(trie/可持久化trie+堆)的更多相关文章

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

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

  2. [十二省联考2019]异或粽子 (可持久化01tire 堆)

    /* 查询异或最大值的方法是前缀和一下, 在01trie上二分 那么我们可以对于n个位置每个地方先求出最大的数, 然后把n个信息扔到堆里, 当我们拿出某个位置的信息时, 将他去除当前最大后最大的信息插 ...

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

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

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

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

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

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

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

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

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

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

  8. [十二省联考2019]异或粽子(堆+可持久化Trie)

    前置芝士:可持久化Trie & 堆 类似于超级钢琴,我们用堆维护一个四元组\((st, l, r, pos)\)表示以\(st\)为起点,终点在\([l, r]\)内,里面的最大值的位置为\( ...

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

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

随机推荐

  1. 【代码笔记】Web-JavaScript-JavaScript JSON

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  2. ArcGIS for JavaScript学习(一)

    一  API准备 从网上下载开发包:ArcGIS for JavaScript(百度网盘地址) sdk中含有API的帮助和例子 2.离线部署(以IIS为例) 配置IIS(详见网络):解压离线包,包中的 ...

  3. 总结:当静态路由和BGP同时存在时路由优选BGP的两种方法

    结论: 方法一.配置BGP协议的外部优先级比静态路由的优先级高,优选BGP. 优点:配置简单. 缺点:全局生效,如果用户有针对某个静态路由想提高优先级,不受动态路由影响,则针对每个静态路由都需要人为提 ...

  4. USGS-EROS项目espa-surface-reflectance中的Landsat8 大气校正LaSRC Version 1.3.0模块利用vs2010编译出windows64位版本(四)

    ,支持一些关键问题: 1    数据初始化问题.该问题是指在linux环境下编程标准c并编译,用户定义的变量默认初始值是0,但在windows 64 win7环境中,变量默认初始值是负值极小.... ...

  5. android引用arr包

    转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/9939494.html android中引用的包一般分为两种: 1.jar包 2.aar包 arr包其实带 ...

  6. python 爬取全本免费小说网的小说

    这几天朋友说想看电子书,但是只能在网上看,不能下载到本地后看,问我有啥办法?我找了好几个小说网址看了下,你只能直接在网上看,要下载txt要冲钱买会员,而且还不能在浏览器上直接复制粘贴.之后我就想到py ...

  7. location.origin不兼容IE8解决方案

    最近项目中遇到一个问题,在ajax跟后台交互时需要传一个全路径url.项目上线后,在谷歌,火狐,360等浏览器访问一切正常.但唯独IE8下出现问题,提示url:undefined ! 这就尴尬了!!! ...

  8. 从0开始的Python学习003序列

    sequence 序列 序列是一组有顺序数据的集合.不知道怎么说明更贴切,因为python的创建变量是不用定义类型,所以在序列中(因为有序我先把它看作是一个有序数组)的元素也不会被类型限制. 序列可以 ...

  9. Kafka相关内容总结(存储和性能)

    Kafka消息的存储 Kafka的设计基于一种非常简单的指导思想:不是要在内存中保存尽可能多的数据,在需要时将这些数据刷新(flush)到文件系统,而是要做完全相反的事情.所有数据都要立即写入文件系统 ...

  10. Tmux 入门

    什么是 Tmux Tmux 官方 Wiki 简单来说,Tmux 是一个能够让你一个窗口当多个窗口使用的终端模拟器.并且你还可以将它放到后台,等到想使用的时候再使用. 为什么要用 Tmux 在服务器上调 ...