对拍拍了 50000 组没有问题,该开 ll 的地方应该都开了,但就是过不掉,玄关求条!
#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define Ckmax(x,y) x=max(x,y)
#define Ckmin(x,y) x=min(x,y)
#define ull unsigned long long
using namespace std;
const int N=5e4+5;
const int IINF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3fll;
inline void FileIO(){
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
template<typename Type>
inline void read(Type &res){
Type x=0,f=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
res=x*f;
}
const int B=30;
int n,a[N];
int trie[N*B][2],cnt[N*B],tot=1,sum[N*B][B];
ll m,k;
const ll mod=1e9+7,Inv2=5e8+4;
ll Mod(ll x){
return (x>=mod)?(x-mod):(x);
}
void Add(ll &x,ll y){
x=Mod(x+y);
}
void Insert(ll x){
int p=1;
for(int i=B-1;i>=0;i--){
int v=x>>i&1;
if(!trie[p][v]) trie[p][v]=++tot;
p=trie[p][v];
cnt[p]++;
for(int j=0;j<B;j++){
if(x>>j&1)
sum[p][j]++;
}
}
}
ll Ask(ll x,ll y){
int p=1; ll res=0;
for(int i=B-1;i>=0;i--){
int w=x>>i&1;
if(y>>i&1){
p=trie[p][!w];
if(!p) break;
}
else{
res+=cnt[trie[p][!w]];
p=trie[p][w];
if(!p) break;
}
}
res+=cnt[p];
return res;
}
ll Check(ll x){
// printf("Check(%d):\n",x);
ll res=0;
for(int i=1;i<=n;i++){
res+=Ask(a[i],x);
}
res>>=1;
// printf("Res=%lld\n",res);
return res;
}
ll XorSum(int p,ll x){
ll res=0;
for(int i=0;i<B;i++){
int v=x>>i&1;
if(!v) Add(res,1ll*sum[p][i]*(1ll<<i)%mod);
else Add(res,1ll*(cnt[p]-sum[p][i])*(1ll<<i)%mod);
}
return res;
}
ll Calc(ll x){
ll res=0; int p=1;
for(int i=B-1;i>=0;i--){
int v=x>>i&1;
int w=k>>i&1;
if(w){
p=trie[p][!v];
if(!p) break;
}
else{
Add(res,XorSum(trie[p][!v],x));
p=trie[p][v];
if(!p) break;
}
}
Add(res,XorSum(p,x));
return res;
}
signed main(){
read(n),read(m);
for(int i=1;i<=n;i++){
read(a[i]);
Insert(a[i]);
}
ll l=0,r=2e9;
k=-1;
while(l<=r){
ll mid=(l+r)>>1;
if(Check(mid)>=m) k=mid,l=mid+1;
else r=mid-1;
}
ll ans=0;
for(int i=1;i<=n;i++) Add(ans,Calc(a[i]));
(ans*=Inv2)%=mod;
ans=Mod(ans+mod-1ll*k%mod*(Check(k)-m)%mod);
printf("%lld\n",ans);
return 0;
}
/*
3 0
1 2 3
*/