题目大意

有\(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. 设计模式之状态模式(State)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  2. TDDL-剖析淘宝TDDL

    TDDL-剖析淘宝TDDL 学习了:https://blog.csdn.net/sumj7011/article/details/78286741 Taobao Distribute Data Lay ...

  3. c语言函数---I

    函数名: imagesize 功 能: 返回保存位图像所需的字节数 用 法: unsigned far imagesize(int left, int top, int right, int bott ...

  4. Eclipse出现&quot;Running Android Lint has encountered a problem&quot;解决方式

    近期打开Eclipse的时候,总是发生这种一个错误:"Running Android Lint has encountered a problem".截图例如以下: . 可是Ecl ...

  5. 百科知识 scm文件如何打开

    用scplayer打开,目前有效的下载链接将是: http://download.csdn.net/download/kevingao/2686778  

  6. 【Python】输出程序运行的百分比

    对于一些大型的Python程序.我们须要在命令行输出其百分比,显得更加友好,以免被人误会程序陷入死循环.假死的窗口. 关键是利用到不换行的输出符\r,\r的输出.将直接覆盖掉此行的内容. 比方例如以下 ...

  7. LoadRunner多负载产生器

    Executive Summary : The following explains why it is necessary to have about 6 load generators when ...

  8. Odoo10对套件的处理

    Odoo10对套件的处理更强, 除了老版本支持的 销售套件, 按组件出货: 现在还增加了 采购套件, 按组件进货     建立 组件产品 KIT     设置 虚件BOM         测试,   ...

  9. Git经常使用命令

    git --version 版本号号git help 帮助gitk 是个图形化的查看工具.gitk --all 所有分支历史-----------------------git pull 先拉git ...

  10. Excel应用----制作二级下拉菜单【转】

    应用: 原始数据源是两列的源数据,那该如何制作二级下拉菜单, 当然可以将这两列的数据源,转换成上面的那种格式,再用上面的方法来制作. 今天教大学的方法是直接通过这种两列式的数据源来制作下拉菜单,如果A ...