题目大意

有\(n\)(\(n\leq5\times10^5\))个数\(a_1,a_2,...a_n\)(\(a_i\leq 2^{32}-1\))

求区间异或和前\(k(k\leq2\times10^5)\)大之和

题解

考虑二分,找出第\(k\)大异或和是多少

将每个位置上的数变成前缀异或和\(s_i\)后,建出可持久化trie树,第\(i\)个版本由\(0,s_1,s_2,..,s_i\)组成,trie树上每个点维护这个点的子树中有几个数

二分\(x\),判断是否有不超过\(k\)个异或和

发现这样时间复杂度为\(\Theta(n\times log^2 a)\),略多

发现一般情况下在线段树上二分时都不是先二分出一个值再查询,而是在线段树上边走边计算

同理,本题就可以维护\(n\)个位置,即当前走到的第\(i(i\in[1,n])\)个版本的trie树的位置

每次判断当前位放1会不会使大于等于当前值的异或和数量少于\(k\),会就走\(a_i\)当前位异或0的方向,反之就走\(a_i\)当前位异或1的方向

算出第\(k\)大异或和后,直接在trie树中dfs找出大于(注意,不能找等于它的,不然会找多)它的异或和,计入答案,顺便记一共加了几个数

\((k-上一步加的数的个数)\)就是等于第\(k\)大异或和的异或和的个数,把这个计入答案

以上两步中走到的点只有大于第\(k\)大异或和的点和它们的父亲,只有\(\Theta(k\times log\space a)\)

总时间复杂度\(\Theta((n+k)\times log\space a)\)

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define maxn 500003
#define maxnd (maxn*33)
#define LL long long
#define int LL
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(LL x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
LL ans,a[maxn],num;;
const int len=31;
int n,k,ch[maxnd][2],val[maxnd],rt[maxn],cntnd,now[maxn],nownum;
void ext(int i)
{
int u,nu=++cntnd;rt[i]=cntnd;
if(i)u=rt[i-1];
else u=0;
dwn(j,len,0)
{
int d=(a[i]&(1ll<<j))>>j;
if(u)val[nu]=val[u]+1,ch[nu][d^1]=ch[u][d^1],u=ch[u][d];
else val[nu]=1;
ch[nu][d]=++cntnd,nu=cntnd;
}
if(u)val[nu]=val[u]+1;
else val[nu]=1;
}
void getans(int u,LL ai,LL xi)
{
if(!ch[u][0]&&!ch[u][1]){if(((LL)ai^(LL)xi)>(LL)num){nownum+=val[u],ans=ans+(LL)((LL)ai^(LL)xi)*val[u];}return;}
if(ch[u][0])getans(ch[u][0],ai,xi<<1);
if(ch[u][1])getans(ch[u][1],ai,xi<<1|1);
return;
}
#define dd(x,y) ((x&(1ll<<y))>>y)
signed main()
{
n=read(),k=read();
rep(i,1,n)a[i]=read()^a[i-1];
rep(i,0,n)ext(i),now[i]=rt[i];
dwn(i,len,0)
{
int tmp=0;
rep(j,1,n)if(now[j]){tmp+=val[ch[now[j]][dd(a[j],i)^1ll]];}
if(tmp+nownum>=k){rep(j,1,n)if(now[j])now[j]=ch[now[j]][dd(a[j],i)^1ll];num=num<<(1ll)|(1ll);}
if(tmp+nownum<k){rep(j,1,n)if(now[j])now[j]=ch[now[j]][dd(a[j],i)];nownum+=tmp;num=num<<(1ll);}
}
nownum=0;
rep(i,1,n)
{
int u=rt[i],vv=0;
dwn(j,len,0)
{
int d=dd(a[i],j),e=dd(num,j);
if(!e&&ch[u][d^1]){getans(ch[u][d^1],a[i],vv<<1|(d^1));}
if(!ch[u][d^e])break;
u=ch[u][d^e],vv=vv<<1|(d^e);
}
}
ans+=(LL)num*(k-nownum);
write(ans);
return 0;
}
/*
3 2
1 2 3
*/
一些感想

sb猎人公会nmsl

并不对劲的loj3048:p5283:[十二省联考]异或粽子的更多相关文章

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

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

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

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

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

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

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

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

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

    感觉不是很难的一题,想了0.5h左右(思路歪了,不过想了一个大常数的两只\(\log\)做法233) 然后码+调了1h,除了一个SB的数组开小外基本上也没什么坑点 先讲一个先想到的方法,我们对于这种问 ...

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

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

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

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

  8. 并不对劲的loj3049:p5284:[十二省联考]字符串问题

    题目大意 给出字符串\(S(|S|\leq2\times10^5)\), \(na(na\leq2\times 10^5)\)个区间\([l_i,r_i]\)表示\(S_{l_i},S_{l_i+1} ...

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

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

随机推荐

  1. go 协程与主线程强占运行

    最近在学习了Go 语言 ,  正好学习到了 协程这一块 ,遇到了困惑的地方.这个是go语言官方文档 . 在我的理解当中是,协程只能在主线程释放时间片后才会经过系统调度来运行协程,其实正确的也确实是这样 ...

  2. DEDECMS5.5怎样调用{dede:field.content/}做简介之类的单独页面?

    很多时候,如果用dede来做一些企业公司网站,或者一些部门网站的时候.需要某些栏目是一个单页的文章,用于公司简介或者企业文化之类的.那么就要用到栏目功能的栏目内容,也就是dede的content标签. ...

  3. Build FTP Server on Windows

    1. Use the self-ftp component service with windows control panel / program / start or close windows ...

  4. 写一个dup2功能同样的函数,不能调用 fcntl 函数,而且要有出错处理

    实现的时候用到系统原来的dup函数 // mydup2.c // 2015/08/17 Lucifer Zhang version1.0 // write my own dup2 function / ...

  5. serialVersionUID的作用以及如何用idea自动生成实体类的serialVersionUID

    转载:http://blog.csdn.net/liuzongl2012/article/details/45168585 serialVersionUID的作用: 通过判断实体类的serialVer ...

  6. C++继承:公有,私有,保护(转)

    公有继承(public).私有继承(private).保护继承(protected)是常用的三种继承方式. 1. 公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时, ...

  7. Solaris 系统启动与关闭

    忘掉root密码 更改内核参数后,重启进不了系统 复制---进入单用户模式----恢复文件 系统突然死机,如何尽量减少数据丢失 Sync 同步命令.将内存内容输入到硬盘,相当于保存文档.   Unix ...

  8. python(31)- 模块练习

    1. 小程序:根据用户输入选择可以完成以下功能:     创意文件,如果路径不存在,创建文件夹后再创建文件     能够查看当前路径     在当前目录及其所有子目录下查找文件名包含指定字符串的文件 ...

  9. 使用Nightwatch.js做基于浏览器的web应用自动测试

    1        安装 1.1   安装Node.js 在http://nodejs.org/ 上下载适合本机系统的安装包运行安装,注意安装选项中选择npm tool以用于后续依赖包的安装. 1.2  ...

  10. ACPI in Linux

    https://01.org/zh/linux-acpi The goal of this project is to enable Linux to take advantage of platfo ...