multiplication
The most difficult part of this problem is preprocessing.
First, set is used to preprocess the maximum and the next maximum of the absolute value of the altitude difference of each point from the back to the front.
Because the subscript of the current city can only be larger, for point i, find the subscript that is closest to its value in the set.
Then the left and right subscripts are processed in set, and the maximum value and the next minimum value are taken.
Pretreatment completed
Think of every small A and B drive as A wheel drive
Then, g[i][j] is used to indicate the point from the ith point after the 2^j wheel drive.
la[i][j] refers to the distance from point I to small A driven by wheel 2^j.
lb[i][j] refers to the distance from point I to small B driven by wheel 2^j.
And then there's multiplication.
It should also be noted that when the complete round can not be carried out, small A may drive another round of car, just judge.
#include <bits/stdc++.h> #define ll long long #define inf 1e9 using namespace std; const ll MAXN=100100; ll n,x0,a[MAXN],b[MAXN],g[MAXN][32]; ll h[MAXN],where,ding,m; ll la[MAXN][32],lb[MAXN][32]; double MIN; set <pair<ll,ll> > s; bool cmp(pair<ll,ll> a,pair<ll,ll> b) { return (abs(a.first-ding)<abs(b.first-ding) || (abs(a.first-ding)==abs(b.first-ding) && h[a.second]<h[b.second])); } int main() { scanf("%lld",&n); for (ll i=1;i<=n;i++) scanf("%lld",&h[i]); a[n]=b[n]=-1;//-1 means no more driving s.insert(make_pair(h[n],n)); b[n-1]=n;a[n-1]=-1; s.insert(make_pair(h[n-1],n-1)); for (ll i=n-2;i>=1;i--)//Preprocessing { bool bl=0; set <pair<ll,ll> > :: iterator it,be; vector <pair<ll,ll> > k; k.clear(); it=s.lower_bound(make_pair(h[i],i)); be=s.begin(); be--; if (it!=s.end()) { k.push_back(*it); it++; bl=1; } if (it!=s.end()) k.push_back(*it); if (bl) it--; it--; if (it!=be) { k.push_back(*it); it--; } if (it!=be) k.push_back(*it);//Handle the left and right 4 points ding=h[i]; sort(k.begin(),k.end(),cmp); b[i]=k[0].second;//Take the maximum a[i]=k[1].second;//Take second big s.insert(make_pair(h[i],i)); } for (ll i=1;i<=n;i++) { g[i][0]=-1; if (a[i]!=-1 && b[a[i]]!=-1) { la[i][0]=abs(h[i]-h[a[i]]); lb[i][0]=abs(h[a[i]]-h[b[a[i]]]); g[i][0]=b[a[i]];//Multiplication pretreatment } } for (ll i=1;i<=30;i++) { for (ll j=1;j<=n;j++) { if (g[j][i-1]!=-1 && g[g[j][i-1]][i-1]!=-1)//Guarantee not to exceed the scope { g[j][i]=g[g[j][i-1]][i-1]; la[j][i]=la[j][i-1]+la[g[j][i-1]][i-1]; lb[j][i]=lb[j][i-1]+lb[g[j][i-1]][i-1];//Doubling } else g[j][i]=-1; } } scanf("%lld",&x0); MIN=1.0e18+10; where=0; for (ll i=1;i<=n;i++) { ll ta,tb,now; ta=tb=0; now=i; for (ll j=30;j>=0;j--)//search { if (g[now][j]!=-1 && ta+tb+la[now][j]+lb[now][j]<=x0) { ta+=la[now][j]; tb+=lb[now][j]; now=g[now][j]; } } if (a[now]!=-1 && ta+tb+abs(h[now]-h[a[now]])<=x0) { ta+=abs(h[now]-h[a[now]]); now=a[now]; } double temp; if (tb==0) temp=1.0e18; else temp=(double)(1.0*ta)/(1.0*tb); if (temp<MIN) { MIN=temp; where=i; } else if (temp==MIN) { if (h[i]>h[where]) where=i; } } printf("%lld\n",where); scanf("%lld",&m); for (ll i=1;i<=m;i++) { ll now,x; scanf("%lld%lld",&now,&x); ll ta,tb; ta=tb=0; for (ll j=30;j>=0;j--) { if (g[now][j]!=-1 && ta+tb+la[now][j]+lb[now][j]<=x) { ta+=la[now][j]; tb+=lb[now][j]; now=g[now][j]; } } if (a[now]!=-1 && ta+tb+abs(h[now]-h[a[now]])<=x) { ta+=abs(h[now]-h[a[now]]); now=a[now]; } printf("%lld %lld\n",ta,tb); } }