CF241B Friends

和Tree and Xor思路一样CF1055F Tree and XOR

直接找到第k大val,可以直接建出trie,然后按位贪心

考虑比val大的数的和

还是用b[i]维护可能和i贡献的trie的位置

当val这一位是0时候,v[i]就可以和ch[b[i]][v[i]>>d&1^1]进行贡献

一个点与一个子树进行贡献,不容易做。

不妨把v进行sort,子树就是区间了!

直接枚举每一位进行xor贡献

O(nlog^2n)

注意,

题目要求(a,b)不等于(b,a)方便起见,k*=2,最后ans/=2

可以最后再取mod

第k大的贡献不会算上,额外考虑,但是注意只是剩下一些个第k大元素。

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=;
const int mod=1e9+;
int v[N],a[N],b[N];
int n;
ll k,val;
int ch[N*+][],tot,l[N*+],r[N*+];
int rt;
int sz[N*+];
int pre[N][][];
ll ans;
void ins(int v,int id){
if(!rt) rt=++tot,l[rt]=,r[rt]=n;
int x=rt;
++sz[rt];
for(reg d=;d>=;--d){
int c=(v>>d)&;
if(!ch[x][c]) ch[x][c]=++tot,l[tot]=id;
x=ch[x][c];
r[x]=id;
++sz[x];
}
}
void fin(){
for(reg i=;i<=n;++i) b[i]=rt;
for(reg d=;d>=;--d){
ll s=,t=;
for(reg i=;i<=n;++i){
s+=sz[ch[b[i]][(v[i]>>d&)^]];
}
if(s<k) k-=s,t=;
else t=,val|=(<<d);
for(reg i=;i<=n;++i){
b[i]=ch[b[i]][(v[i]>>d&)^t];
}
}
} ll con(int l,int r,ll v){
if(!l||!r) return ;
--l;
// cout<<" con "<<l<<" "<<r<<" v "<<v<<endl;
ll ret=;
for(reg d=;d>=;--d){
int c=v>>d&;
ret=ret+(ll)(pre[r][d][c^]-pre[l][d][c^])*(1LL<<d);
}
return ret;
}
void calc(){
for(reg i=;i<=n;++i) b[i]=rt;
for(reg d=;d>=;--d){
int t=val>>d&;
// cout<<" dd "<<d<<" tt "<<t<<endl;
if(!t){
for(reg i=;i<=n;++i){
int c=v[i]>>d&;
ans+=con(l[ch[b[i]][c^]],r[ch[b[i]][c^]],v[i]);
}
}
for(reg i=;i<=n;++i){
b[i]=ch[b[i]][(v[i]>>d&)^t];
}
}
}
int main(){
rd(n);rd(k);
if(k==){
puts("");return ;
}
k=k*; for(reg i=;i<=n;++i){
rd(v[i]);//++mp[v[i]];
}
sort(v+,v+n+);
for(reg i=;i<=n;++i) ins(v[i],i);
// cout<<" kk "<<k<<endl;
fin();
ans+=k*val;
for(reg i=;i<=n;++i){
for(reg d=;d>=;--d){
pre[i][d][]=pre[i-][d][];
pre[i][d][]=pre[i-][d][];
pre[i][d][(v[i]>>d)&]++;
}
}
// cout<<" ans1 "<<ans<<endl;
calc();
ans/=;
ot(ans%mod);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/

CF241B Friends的更多相关文章

  1. bzoj2006 [NOI2010]超级钢琴 (及其拓展)

    bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...

随机推荐

  1. 如何解决IntelliJ在打包Maven项目时不打包配置文件

    在pom文件中加上你的配置文件夹目录: <build> <resources> <resource> <directory>src/res</di ...

  2. PHP核心编程--目录操作(包含文件操作)

    一.目录操作 1.    创建目录 创建目录mkdir(目录名称)  //返回值为布尔 一次性创建主目录及其子目录 判断是不是一个目录is_dir  //返回true,false 判断目录或文件是否存 ...

  3. GNU的__builtin_popcount函数

    用来计算32位的unsigned int中的1的个数, 其内部实现是根据查表法来计算的.

  4. 【JZOJ4743】【NOIP2016提高A组模拟9.2】积木

    题目描述 输入 输出 样例输入 3 8 7 6 3 9 4 1 10 5 输出 18 数据范围 样例解释 解法 容易从n<=15得出可以使用状态压缩动态规划. 设f[i][j][k]表示01状态 ...

  5. c++之手写strcmp

    int strcmp(const char* str1, const char*str2){ assert(str1 != NULL&&str2 != NULL); while (*s ...

  6. poj1087&&hdu1526 最大流

    多源多汇. 比较明显的建图.对于电器,可以从源点与各个电器相连,容量为1,表示这个电器有1个,然后对于各种接头,那可以各个接头与汇点相连,容量为1,表示每个接头只能用一次. 然后对于能够相互转换的接头 ...

  7. UVA_694:The Collatz Sequence

    Language: C++ 4.8.2 #include<stdio.h> int main(void) { long long int m, n, copy_m; ; ; ) { sca ...

  8. 修改eclipse默认注释

    windows-->preference-->Java-->Code Style-->Code Templates -->Comments :注释--> ... 关 ...

  9. SQL注入原理讲解,很不错!

    SQL注入原理讲解,很不错! 原文地址:http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序员 ...

  10. MySQL按天,按周,按月,按时间段统计【转载】

    自己做过MySQL按天,按周,按月,按时间段统计,但是不怎么满意,后来找到这位大神的博客,转载一下,谢谢这位博主的分享 知识点:DATE_FORMAT 使用示例 select DATE_FORMAT( ...