Language: C++

#include "bits/stdc++.h"
 
using namespace std;
#define REP(i, n) for(ll i = 0;i < n;i++)
#define ll long long
#define ull unsigned long long
#define uint unsigned int
 
 
uint digit_level;
uint digitN;
 
uint MODP,MODP0,MODP1,MODP2;
uint MODP_WnSqrt;
uint MODP_Wn;
 
uint CreateWnSqrt(uint a,uint m,uint n_level){
  ull ans=a;
  ull ulm=m;
  for(int i=0;i<n_level-digit_level-1;i++){
    ans=ans*ans%ulm;
  }      
  return (uint)ans;
}
 
 
 
//aの逆元を返す mod m
uint modinv(uint a,uint m){
    ll b = m;
    ll u = 1;
    ll v = 0;
    ll t,tmp;
    while (b!=0){
        t = a / b;
        a -= t * b;
        tmp=a;
        a=b;
        b=tmp;
        u -= t * v;
        tmp = u;
        u = v;
        v = tmp;
    }
    u %= m;
    if (u < 0)u += m;
    return (uint)u;
}
 
 
//aのn乗 mod c
uint expmod(uint a,uint n,uint MOD){
  ull ans=1ULL,aa=a,beki=n,ulm=(ull)MOD;
  for(int i=0;i<63;i++){
    if (beki%2==1) ans=ans*aa%ulm;
    aa=aa*aa%ulm;
    beki/=2;
    if (beki==0)break;
  }
  return (uint)ans;
}
 
 
uint expmod0(uint a,uint n,uint MOD){
  
  if (MOD==2013265921)
  {
    return MTABLE0[n];
  }else{
    return MTABLE1[n];
  }
}
 
 
 
//garnerのアルゴリズム、3変数ver
void Garner(ll a_,ll b_,ll ar_,ll br_,ll *rx){
  ll a = a_;
  ll b = b_;
  ll ar = ar_;
  ll br = br_;
  ll mab=(ll)modinv(a,b);
  ll x=(br - ar) * mab % b;
  if (x<0){
    x+=b;
  }
  x = ar + x * a;
  *rx=x;
/*
  ll tmp=((cr - x % c)+c)%c;
  ull px=tmp * (ull)modinv(a,c) % c * (ull)modinv(b,c) % c * a;//*b
 
  ull px_hi=px/(1ULL<<32ULL);
  ull px_lo=px%(1ULL<<32ULL);
  px_hi*=b;
  px_lo*=b;
  px_hi+=px_lo/(1ULL<<32ULL);
  px_lo%=(1ULL<<32ULL);
  px_lo+=x;
  px_hi+=px_lo/(1ULL<<32ULL);
  px_lo%=(1ULL<<32ULL);
 
  *rx_lo=(uint)(px_lo);
  *rx_md=(uint)(px_hi%(1ULL<<32ULL));
  *rx_hi=(uint)(px_hi/(1ULL<<32ULL));
  */
  }
 
 
void iFMT(vector<uint>& arrayA){
  uint t2,t0,t1,arrayAt0,arrayAt1,w0,w1;
    for(int i=0;i<digit_level;i++){
      uint loopCnt_Pow2 = 1 << i;
      for(int idx=0;idx<digitN/2;idx++){
        t2 = idx % loopCnt_Pow2;
        t0 = idx * 2 - t2;
        t1 = t0 + loopCnt_Pow2;
        arrayAt0 = arrayA[t0];
        arrayAt1 = arrayA[t1];
        w0 = expmod0(MODP_Wn, digitN - t2 * (1 << (digit_level - 1 - i)),MODP);
        w1 = (uint)((ull)arrayAt1 * (ull)w0 % (ull)MODP);
        arrayAt1=arrayAt0 + MODP - w1;
        if (arrayAt1>=MODP)arrayAt1-=MODP;
        arrayAt0+=w1;
        if (arrayAt0>=MODP)arrayAt0-=MODP;
 
        arrayA[t1] = arrayAt1;
        arrayA[t0] = arrayAt0;
      }
    }
  }
 
 
void uFMT(vector<uint>& arrayA){
  uint t2,t0,t1,arrayAt0,arrayAt1,w0,w1,r0,r1;
    for(int i=0;i<digit_level;i++){
      uint loopCnt_Pow2 = 1 << (digit_level - i - 1);
      for(int idx=0;idx<digitN/2;idx++){
          t2 = idx % loopCnt_Pow2;
          t0 = idx * 2 - t2;
          t1 = t0 + loopCnt_Pow2;
          arrayAt0 = arrayA[t0];
          arrayAt1 = arrayA[t1];
          w0 = expmod0(MODP_Wn, t2 * (1 << i),MODP);
          r0 = (arrayAt0 - arrayAt1 + MODP);
          if (r0>=MODP)r0-= MODP;
          r1 = (arrayAt0 + arrayAt1);
          if (r1>=MODP)r1-= MODP;
          w1 = (uint)((ull)r0 * (ull)w0 % (ull)MODP);
          arrayA[t1] = w1;
          arrayA[t0] = r1;
      }
    }
  }
 
 
void DivN(vector<uint>& arrayA){
  ull digitN_r = modinv(digitN, MODP);
  for(int i=0;i<digitN;i++){
    ull ret = (ull)(arrayA[i]) * digitN_r % (ull)MODP;
    arrayA[i]=(uint)(ret);
  }
}
 
 
void PreNegFMT(vector<uint>& arrayA){
  for(int i=0;i<digitN;i++){
    arrayA[i] = (uint)((ull)arrayA[i] * (ull)expmod(MODP_WnSqrt, i,MODP) % (ull)MODP);
  }
}
 
void PostNegFMT(vector<uint>& arrayA){
  for(int i=0;i<digitN;i++){
    arrayA[i] = (uint)((ull)arrayA[i] * (ull)expmod(MODP_WnSqrt, digitN * 2 - i,MODP) % (ull)MODP);
  }
}
 
 
//    #A*Bの畳み込み結果を返す
//    #上位桁、下位桁を復元して1倍の要素数で返す
void Convolution(vector<uint>& A_,vector<uint>& B_,vector<uint>& E,int pno){
  //#正巡回
  vector<uint> A1(digitN),B1(digitN),Cpos(digitN);//,A2(digitN),B2(digitN),Cpos(digitN),Cneg(digitN);
  for(int i=0;i<digitN;i++){
    A1[i]=A_[i]%MODP;
  }
  for(int i=0;i<digitN;i++){
    B1[i]=B_[i]%MODP;
  }
  uFMT(A1);
  uFMT(B1);
  for(int i=0;i<digitN;i++){
    Cpos[i]=(uint)((ull)A1[i]*(ull)B1[i]%(ull)MODP);
  }
  iFMT(Cpos);
  DivN(Cpos);
 
/*
  //# 負巡回
  PreNegFMT(A2);
  PreNegFMT(B2);
  uFMT(A2);
  uFMT(B2);
  for(int i=0;i<digitN;i++){
    Cneg[i]=(uint)((ull)A2[i]*(ull)B2[i]%(ull)MODP);
  }
  iFMT(Cneg);
  DivN(Cneg);
  PostNegFMT(Cneg);
*/
  for(int i=0;i<digitN;i++){
    //#上位桁、下位桁 復元
    /*
    uint Elo = (Cpos[i] + Cneg[i]) % MODP;
    Elo = (Elo + Elo % 2 * MODP) /2;
 
    uint Ehi = (Cpos[i] - Cneg[i] + MODP) % MODP;
    Ehi = (Ehi + Ehi % 2 * MODP) / 2;
  */
    E[i] = Cpos[i];
    //E[digitN+i] = Ehi;
  }
}
 
//#E0,E1,E2を使ってgarnerでEを復元して繰り上がり処理
void Carrying(vector<uint>& E0,vector<uint>& E1,vector<ll>& E){
  uint upg=0;
  ll out_;
  //uint out_lo,out_md,out_hi;
  for(int i=0;i<digitN;i++){
    upg=0;
    Garner(MODP0,MODP1, E0[i], E1[i],&out_);
 
    E[i]=out_;//(ll)out_lo+(1LL<<32LL)*out_md;
    /*
    if (E[i]>E[i]+out_lo){
      upg=1;
    }
    E[i]+=out_lo;
 
    if (out_md==4294967295){
      if (upg==1)out_hi++;
    }
    out_md+=upg;
    if (i<digitN-1){
      if (E[i+1]>E[i+1]+out_md){
        out_hi++;
      }
    }
    E[i+1]+=out_md;
 
    upg=0;
    if (i<digitN-2){
      if (E[i+2]>E[i+2]+out_hi){
        upg=1;
      }
    }
    E[i+2]+=out_hi;
    
    for(int j=i+3;j<digitN;j++){
      if (upg==0)break;
      E[j]+=upg;
      if (E[j]!=0)upg=0;
    }
    */
 
  }
}
 
 
 
 

vector<uint> MTABLE0;
vector<uint> MTABLE1;
 
ll n,m;
int main(){
  
  ll ans=0;
  cin >> n >> m;
  vector<int> a(n);
  REP(i,n) cin>>a[i];
 
  //sort(a.begin(), a.end());
 

  digit_level=18;
  digitN=1<<digit_level;//乗算前の要素数。乗算結果は2*digitN要素数になる
  MTABLE0.resize(1<<(digit_level+1))
  MTABLE1.resize(1<<(digit_level+1))

 
 
  MODP0=2013265921;
  MODP=MODP0;
  MODP_WnSqrt=CreateWnSqrt(52278,2013265921,27);
  MODP_Wn=(uint)((ull)MODP_WnSqrt*(ull)MODP_WnSqrt%(ull)MODP);
  REP(i,digitN*2){
    MTABLE0[i]=expmod(MODP_Wn, i,MODP);
  }
  
  MODP1=1811939329;
  MODP=MODP1;
  MODP_WnSqrt=CreateWnSqrt(59189,1811939329,26);
  MODP_Wn=(uint)((ull)MODP_WnSqrt*(ull)MODP_WnSqrt%(ull)MODP);
  REP(i,digitN*2){
    MTABLE1[i]=expmod(MODP_Wn, i,MODP);
  }
  
 
 
 
 
  vector<uint> A_(digitN),B_(digitN),E0(digitN),E1(digitN),E2(digitN);
  for(int i=0;i<n;i++){
    A_[a[i]]++;
    B_[a[i]]++;
  }
 
  //Pだけ変えただけで、同じのを3つべた書きしている
  MODP0=2013265921;
  MODP=MODP0;
  MODP_WnSqrt=CreateWnSqrt(52278,2013265921,27);
  MODP_Wn=(uint)((ull)MODP_WnSqrt*(ull)MODP_WnSqrt%(ull)MODP);
  Convolution(A_,B_,E0,0);
 
  MODP1=1811939329;
  MODP=MODP1;
  MODP_WnSqrt=CreateWnSqrt(59189,1811939329,26);
  MODP_Wn=(uint)((ull)MODP_WnSqrt*(ull)MODP_WnSqrt%(ull)MODP);
  Convolution(A_,B_,E1,1);
/*
  MODP2=2013265921;
  MODP=MODP2;
  MODP_WnSqrt=CreateWnSqrt(52278,2013265921,27);
  MODP_Wn=(uint)((ull)MODP_WnSqrt*(ull)MODP_WnSqrt%(ull)MODP);
  Convolution(A_,B_,E2,2);
*/
 
  vector<ll> E(digitN,0);//結果格納変数
  Carrying(E0,E1,E);
 
 
 
 
  for(ll i=digitN-1;i>=0;i--){
    if (m>E[i]){
      m-=E[i];
      ans+=E[i]*i;
    }else{
      ans+=m*i;
      break;
    }
  }
 
 
 
  cout<<ans<<endl;
  return 0;
}

Compiler output:
a.cc: In function 'unsigned int expmod0(unsigned int, unsigned int, unsigned int)':
a.cc:68:12: error: 'MTABLE0' was not declared in this scope
   68 |     return MTABLE0[n];
      |            ^~~~~~~
a.cc:70:12: error: 'MTABLE1' was not declared in this scope
   70 |     return MTABLE1[n];
      |            ^~~~~~~
a.cc: In function 'int main()':
a.cc:290:37: error: expected ';' before 'MTABLE1'
  290 |   MTABLE0.resize(1<<(digit_level+1))
      |                                     ^
      |                                     ;
  291 |   MTABLE1.resize(1<<(digit_level+1))
      |   ~~~~~~~