原文链接www.cnblogs.com/zhouzhendong/p/LOJ3048.html

题解

  $O(n\log^2 {a_i})$ 的做法比较简单:

  1. 求出第 k 大的是什么: 二分答案,在Trie树上统计一下答案。

  2. 求出前 k 大的和:已经知道了第 k 大的数值,那么,只要再在 Trie 树上走一趟就好了。

  这两部分直接暴力都是 $O(n\log^2 a_i)$ 的。

  那么我们来稍微优化一下:

  对于 1. ,我们改成 Trie 树上二分,变成了 $O(n\log a_i)$ 的。

  对于 2. ,我们发现:这个 Trie 最多有 O(n) 个分叉点。而且在 2 操作中,搜索子树的次数也是 O(n) 的。那么,如果我们可以预处理出每一个节点代表的子树中,每一种二进制位的出现次数,就可以解决问题。处理处全部的信息显然是不可能的,我们考虑只处理每一个分叉的两个儿子,由于它是 O(n) 的,所以时间复杂度降到 $O(n \log a_i)$ 。

  接下来的代码是 $O(n\log ^2 a_i)$ 的代码。

  至于我开的数据范围以及 __int128 为何使用,我给出一个解释:某神仙把数据范围改成了 n<=7.5e5, k<=n(n-1)/2 。然而我写两个log卡常数没有卡过去。

代码

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> vi;
typedef unsigned uint;
namespace IO{
const int Len=1<<20;
char Ibuf[Len+1],*Is=Ibuf,*It=Ibuf;
char gc(){
if (Is==It){
It=(Is=Ibuf)+fread(Ibuf,1,Len,stdin);
if (Is==It)
return EOF;
}
return *Is++;
}
}
#define getchar IO::gc
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=750005;
int n,bt=31;
LL k;
LL a[N],s[N];
int size[N*33],Next[N*33][2];
uint val[N*33];
int cnt=1;
void Insert(LL v){
int x=1,t;
size[x]++;
Fod(i,bt,0){
t=v>>i&1;
if (!Next[x][t])
Next[x][t]=++cnt,val[cnt]=val[x]|((LL)t)<<i;
x=Next[x][t];
size[x]++;
}
}
LL calc(int a,int b){
return a==b?((LL)size[a]*(size[a]-1))>>1:(LL)size[a]*size[b];
}
__int128 ans=0;
int *c0,*c1;
void get(int x,int d){
if (Next[x][0]){
c0[d]+=size[Next[x][0]];
get(Next[x][0],d-1);
}
if (Next[x][1]){
c1[d]+=size[Next[x][1]];
get(Next[x][1],d-1);
}
}
void calc2(int x,int y,int d){
static int bitx[2][33],bity[2][33];
clr(bitx),clr(bity);
c0=bitx[0],c1=bitx[1],get(x,d);
if (x!=y){
c0=bity[0],c1=bity[1],get(y,d);
For(i,0,d)
ans+=(__int128)(bitx[0][i]*bity[1][i]+bitx[1][i]*bity[0][i])<<i;
}
else {
For(i,0,d)
ans+=(__int128)(bitx[0][i]*bitx[1][i])<<i;
}
ans+=(__int128)calc(x,y)*(val[x]^val[y]);
}
LL now=0,ub,res_cnt=0,tmp=0;
void dfs(int x,int y,int d){
uint v=val[x]^val[y];
if (v>=ub)
return (void)(tmp+=calc(x,y));
if ((1LL<<(d+1))+v<=ub)
return;
if (Next[x][0]){
if (Next[y][0])
dfs(Next[x][0],Next[y][0],d-1);
if (Next[y][1])
dfs(Next[x][0],Next[y][1],d-1);
}
if (Next[x][1]){
if (Next[y][1])
dfs(Next[x][1],Next[y][1],d-1);
if (Next[y][0]&&x!=y)
dfs(Next[x][1],Next[y][0],d-1);
}
}
void dfs2(int x,int y,int d){
uint v=val[x]^val[y];
if (v>=ub)
return calc2(x,y,d);
if ((1LL<<(d+1))+v<=ub)
return;
if (Next[x][0]){
if (Next[y][0])
dfs2(Next[x][0],Next[y][0],d-1);
if (Next[y][1])
dfs2(Next[x][0],Next[y][1],d-1);
}
if (Next[x][1]){
if (Next[y][1])
dfs2(Next[x][1],Next[y][1],d-1);
if (Next[y][0]&&x!=y)
dfs2(Next[x][1],Next[y][0],d-1);
}
}
void write(__int128 x){
if (x>9)
write(x/10);
putchar('0'+x%10);
}
int main(){
n=read(),k=read();
For(i,1,n)
a[i]=read();
s[0]=0;
For(i,1,n)
s[i]=s[i-1]^a[i];
s[++n]=0;
For(i,1,n)
Insert(s[i]);
Fod(i,bt,0){
ub=now|1LL<<i;
tmp=0,dfs(1,1,bt);
if (tmp>=k)
now=ub,res_cnt=tmp;
}
ub=now;
dfs2(1,1,bt);
ans-=(__int128)(res_cnt-k)*ub;
write(ans),putchar('\n');
return 0;
}

  

LOJ#3048. 「十二省联考 2019」异或粽子 Trie的更多相关文章

  1. LOJ#3048. 「十二省联考 2019」异或粽子(trie树+堆)

    题面 传送门 题解 我们先把它给前缀异或和一下,然后就是要求前\(k\)大的\(a_i\oplus a_j\).把\(k\)乘上个\(2\),变成前\(2k\)大的\(a_i\oplus a_j\), ...

  2. LOJ3048 「十二省联考 2019」异或粽子

    题意 题目描述 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 $n$ 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 $1$ 到 $n$.第 $i$ 种馅儿具 ...

  3. 「洛谷5283」「LOJ3048」「十二省联考2019」异或粽子【可持久化01trie+优先队列】

    题目链接 [洛谷传送门] [LOJ传送门] 题目大意 让你求区间异或和前\(k\)大的异或和的和. 正解 这道题目是Blue sky大佬教我做的(祝贺bluesky大佬进HA省A队) 我们做过某一些题 ...

  4. 「十二省联考 2019」异或粽子——tire树+堆

    题目 [题目描述] 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 $n$ 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 $1$ 到 $n$.第 $i$ 种馅 ...

  5. LOJ #3049. 「十二省联考 2019」字符串问题

    LOJ #3049. 「十二省联考 2019」字符串问题 https://loj.ac/problem/3049 题意:给你\(na\)个\(A\)类串,\(nb\)个\(B\)类串,\(m\)组支配 ...

  6. LOJ#3052. 「十二省联考 2019」春节十二响(启发式合并)

    题面 传送门 题解 先考虑一条链的情况,对于\(1\)号点来说,肯定是左子树中最大值和右子树中最大值一组,左子树中次大值和右子树中次大值一组--以此类推 那么如果不是一条链呢?我们把所有的链合并起来就 ...

  7. 「ZJOI2019」&「十二省联考 2019」题解索引

    「ZJOI2019」&「十二省联考 2019」题解索引 「ZJOI2019」 「ZJOI2019」线段树 「ZJOI2019」Minimax 搜索 「十二省联考 2019」 「十二省联考 20 ...

  8. 【LOJ】#3051. 「十二省联考 2019」皮配

    LOJ#3051. 「十二省联考 2019」皮配 当时我在考场上觉得这题很不可做... 当然,出了考场后再做,我还是没发现学校和城市是可以分开的,导致我还是不会 事实上,若一个城市投靠了某个阵营,学校 ...

  9. 「十二省联考 2019」皮配——dp

    题目 [题目描述] #### 题目背景一年一度的综艺节目<中国好码农>又开始了.本季度,好码农由 Yazid.Zayid.小 R.大 R 四位梦想导师坐镇,他们都将组建自己的梦想战队,并率 ...

随机推荐

  1. 通过<meta>标签指定IE的文档模式实现CSS3兼容

    今天发现之前做好的一个页面在IE中打开显示的效果不正常,本地和服务器上显示的是两种不同的样式. 经过确认文档内容和CSS都是一样的. 通过IE F12(开发人员工具)发现不正常的样式 浏览器文档模式自 ...

  2. git bash 支持中文

      1. 编辑etc\gitconfig文件,在文件末尾增加以下内容: [gui] encoding = utf-8 #代码库统一使用utf-8 pathnameencoding = utf-8 #支 ...

  3. Java(13) 抽象和封装

    一.简述从现实世界中抽象出类的步骤 第一:找出分类(分析出类) 第二:找出类的特征(分析类的相关属性) 第三:找出类的行为(分析类的方法) 二.常量(经常出现的变量值) 2.1 语法: public ...

  4. git命令之git mergetool vi非正常退出.swp删除不了的问题

    1.git   pull命令产生无法merge的错误 使用了 git  mergetool命令然后...傻逼了 进入了vi操作界面,不会操作,非正常退出... 然后就产生了.swp相关文件,死活删除不 ...

  5. 2018-2019-2 网络对抗技术 20165221 Exp3 免杀原理与实践

    2018-2019-2 网络对抗技术 20165221 Exp3 免杀原理与实践 基础问题回答 杀软是如何检测出恶意代码的? 主要依托三种恶意软件检测机制. 基于特征码的检测:一段特征码就是一段或者多 ...

  6. P5284 [十二省联考2019]字符串问题

    这是一道涵盖了字符串.图论.数据结构三个方面的综合大题. 把这道题放在D1T2的人应该拖出去打 前置芝士 首先,您至少要会topsort. 其次,如果您只想拿个暴力分,字符串Hash就足够了:如果您想 ...

  7. OSG开源教程(转)

    例:geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); 来指定要利用这些数据生成一个怎么样的形状. ...

  8. Nginx:Linux下安装Nginx与配置

    准备目录 [root@sijizhen ~]# mkdir /usr/local/nginx [root@sijizhen ~]# cd /usr/local/nginx/ 下载 1.Nginx,在h ...

  9. 【原创】大数据基础之Logstash(4)高可用

    logstash高可用体现为不丢数据(前提为服务器短时间内不可用后可恢复比如重启服务器或重启进程),具体有两个方面: 进程重启(服务器重启) 事件消息处理失败 在logstash中对应的解决方案为: ...

  10. Springboot2新特性概述

    官方说明: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes 起码 JDK 8 和支持 ...