This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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;
struct Vector{
ll data[1000000];
int size;
Vector(){
memset(data, -1, sizeof data);
size=0;
}
void reverse(){
std::reverse(data, data+size);
}
void resize(int x){
while (size>x) data[--size]=-1;
while (size<x) data[size++]=-1;
}
void pop_back(){
data[--size]=-1;
}
} f;
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;
f.reverse();
f.resize(f.size+szl);
f.reverse();
f.resize(f.size+szr);
for (auto &i:v){
ll val=i.first, cnt=i.second;
if (val>0){
for (int j=f.size-1; j>=val; --j){
if (f.data[j-val]!=-1) f.data[j]=max(f.data[j], f.data[j-val]+cnt);
}
}else{
for (int j=0; j-val<f.size; ++j){
if (f.data[j-val]!=-1) f.data[j]=max(f.data[j], f.data[j-val]+cnt);
}
}
}
f.reverse();
while (f.size && f.data[f.size-1]==-1){
tl+=power2;
f.pop_back();
}
f.reverse();
while (f.size && f.data[f.size-1]==-1){
tr-=power2;
f.pop_back();
}
if (!f.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.data[0]=a[m], f.size=1;
for (int i=0; i<50; ++i){
dp(1ll<<i, v[i]);
if (abs(tl-L)>>i&1){
tl+=1ll<<i;
if (!f.size) impossible();
f.reverse();
f.pop_back();
f.reverse();
}
if (abs(tr-L)>>i&1){
tr-=1ll<<i;
if (!f.size) impossible();
f.pop_back();
}
for (int j=0; j<f.size; j+=2) f.data[j/2]=f.data[j];
f.resize(f.size/2+1);
}
if (tl>L || tr<L) impossible();
cout << f.data[(L-tl)>>50] << '\n';
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |