题面
https://www.luogu.org/problem/P1081
题解
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cassert>
using namespace std;
const long long INF=100000000000LL;
struct city{
int num;
long long h;
bool operator < (const city rhs) const {
return h<rhs.h;
}
};
set<city> s;
vector <int> son[205000];
int fa[205000],f[205000][20],n,m,p;
long long h[105000],sum1[205000],sum2[205000],sum0[205000],x0;
bool vis[205000];
double val;
long long abq(long long x){
if (x>=0) return x; else return -x;
}
bool smaller(int x,city yuan,city now){
if (abq(now.h-h[x])<abq(yuan.h-h[x])||
(abq(now.h-h[x])==abq(yuan.h-h[x])&&now.h<yuan.h)) return true; else return false;
}
double fabs(double x){
if (x>=0) return x; else return -x;
}
long long hei(int x){
if (x>n) return h[x-n]; else return h[x];
}
bool dengyu(double x,double y){
if (fabs(x-y)<=1e-6) return true; else return false;
}
set<city>::iterator it,pit,ppit,sit,ssit,nul;
city mym,smym;
void maketree(int x){
int i,l=son[x].size();
if (fa[x]!=-1) f[x][0]=fa[x]; else f[x][0]=x;
for (i=1;i<=19;i++) f[x][i]=f[f[x][i-1]][i-1];
if (fa[x]!=-1){
sum0[x]=sum0[fa[x]]+abq(hei(fa[x])-hei(x));
if (x>n) sum1[x]=sum1[fa[x]]+abq(hei(fa[x])-hei(x)),sum2[x]=sum2[fa[x]];
else sum2[x]=sum2[fa[x]]+abq(hei(fa[x])-hei(x)),sum1[x]=sum1[fa[x]];
}
for (i=0;i<l;i++) maketree(son[x][i]);
}
int dfs(int x){
int i;
long long sum=0;
for (i=19;i>=0;i--) if (sum0[x]-sum0[f[x][i]]+sum<=x0) {
sum+=sum0[x]-sum0[f[x][i]];
x=f[x][i];
}
return x;
}
set<city> empty;
int main(){
int i,ss;
city now;
nul=empty.begin();
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%lld",&h[i]);
for (i=n;i>=1;i--) {
now=(city){i,h[i]};
s.insert(now);
it=s.lower_bound(now);
ppit=pit=sit=ssit=it;
if (pit!=s.begin()) {
pit--; ppit--;
if (ppit!=s.begin()) ppit--; else ppit=nul;
}
else ppit=pit=nul;
++sit; ++ssit;
if (sit==s.end()) ssit=sit=nul;
else {
++ssit;
if (ssit==s.end()) ssit=nul;
}
mym=(city){2*n+1,INF};
smym=(city){2*n+1,INF};
if (ppit!=nul && smaller(i,mym,*ppit)) smym=mym,mym=*ppit;
else if (ppit!=nul && smaller(i,smym,*ppit)) smym=*ppit;
if (pit!=nul && smaller(i,mym,*pit)) smym=mym,mym=*pit;
else if (pit!=nul && smaller(i,smym,*pit)) smym=*pit;
if (sit!=nul && smaller(i,mym,*sit)) smym=mym,mym=*sit;
else if (sit!=nul && smaller(i,smym,*sit)) smym=*sit;
if (ssit!=nul && smaller(i,mym,*ssit)) smym=mym,mym=*ssit;
else if (ssit!=nul && smaller(i,smym,*ssit)) smym=*ssit;
if (mym.h!=INF) fa[i]=n+mym.num,son[n+mym.num].push_back(i); else fa[i]=-1;
if (smym.h!=INF) fa[n+i]=smym.num,son[smym.num].push_back(n+i); else fa[n+i]=-1;
}
scanf("%lld",&x0);
scanf("%d",&m);
for (i=2*n;i>=1;i--) if (fa[i]==-1) {
sum0[i]=sum1[i]=sum2[i]=0;
maketree(i);
}
val=987654322*987654321LL; p=2*n+1;
h[p]=987654322*987654321LL;
double s1,s2,ans;
int end;
for (i=n+1;i<=2*n;i++) {
end=dfs(i);
if (end!=i) {
s1=sum1[i]-sum1[end]; s2=sum2[i]-sum2[end];
if (s2==0) ans=INF; else ans=s1/s2;
if (ans<val || (dengyu(ans,val)&& h[i-n]>h[p])) val=ans,p=i-n;
}
}
printf("%d\n",p);
for (i=1;i<=m;i++) {
scanf("%d %lld",&ss,&x0);
end=dfs(n+ss);
printf("%lld %lld\n",sum1[n+ss]-sum1[end],sum2[n+ss]-sum2[end]);
}
}