Submission #1074846

#TimeUsernameProblemLanguageResultExecution timeMemory
1074846huutuanUplifting Excursion (BOI22_vault)C++14
100 / 100
4475 ms4180 KiB
#include <bits/stdc++.h>

using namespace std;

using ll=long long;
// #define int long long

const int M=310;
const ll inf=3e18;
int m;
ll L, a[M*2];

void impossible(){
   cout << "impossible\n";
   exit(0);
}

ll tl, tr;
ll f[1000000];
int size;

void reverse(){
   reverse(f, f+size);
}

void resize(int x){
   while (size>x) f[--size]=-1;
   while (size<x) f[size++]=-1;
}

void pop_back(){
   f[--size]=-1;
}

void dp(ll power2, vector<pair<ll, ll>> v){
   ll szl=max(0ll, min(m*m*2ll, (tl-(-inf))/power2));
   ll szr=max(0ll, min(m*m*2ll, (inf-tr)/power2));
   tl-=szl*power2, tr+=szr*power2;
   reverse();
   resize(size+szl);
   reverse();
   resize(size+szr);
   for (auto &i:v){
      ll val=i.first, cnt=i.second;
      if (val>0){
         for (int j=size-1; j>=val; --j){
            if (f[j-val]!=-1) f[j]=max(f[j], f[j-val]+cnt);
         }
      }else{
         for (int j=0; j-val<size; ++j){
            if (f[j-val]!=-1) f[j]=max(f[j], f[j-val]+cnt);
         }
      }
   }
   reverse();
   while (size && f[size-1]==-1){
      tl+=power2;
      pop_back();
   }
   reverse();
   while (size && f[size-1]==-1){
      tr-=power2;
      pop_back();
   }
   if (!size) impossible();
   return;
}

vector<pair<ll, ll>> v[50];

int32_t main(){
   ios_base::sync_with_stdio(false);
   cin.tie(nullptr);
   cin >> m >> L;
   for (int i=-m; i<=m; ++i) cin >> a[m+i];
   for (int i=-m; i<=m; ++i) if (i){
      ll val=i, cnt=0;
      while (val%2==0) val/=2, ++cnt;
      for (int j=0; j<50; ++j) if (a[m+i]>=(1ll<<j)) v[j+cnt].emplace_back(val, 1ll<<j), a[m+i]-=1ll<<j;
      for (int j=0; j<50; ++j) if (a[m+i]>>j&1) v[j+cnt].emplace_back(val, 1ll<<j);
   }
   tl=0, tr=0, f[0]=a[m], size=1;
   for (int i=0; i<50; ++i){
      dp(1ll<<i, v[i]);
      if (abs(tl-L)>>i&1){
         tl+=1ll<<i;
         if (!size) impossible();
         reverse();
         pop_back();
         reverse();
      }
      if (abs(tr-L)>>i&1){
         tr-=1ll<<i;
         if (!size) impossible();
         pop_back();
      }
      for (int j=0; j<size; j+=2) f[j/2]=f[j];
      resize(size/2+1);
   }
   if (tl>L || tr<L) impossible();
   cout << f[(L-tl)>>50] << '\n';
   return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...