1.首先确定人及地点可以确定路径
2.所以对应多种情况访问,我们就用dp记录所有情况,因为换人和路径都可用dp处理
3.路径大采取倍增的方式,对于固定的路径长采用二进制的方式访问(log优化)
4.multiset可用于重复 元素自动排序 访问需要i++ i--(log)
5.有序存贮访问全部可以达到单向动态记录
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
const int Inf = 2e9;
struct one{
int h,id;
friend bool operator < (one a,one b)
{
return a.h<b.h;
}
};
ll f[18][100005][2],da[18][100005][2],db[18][100005][2];
multiset<one>s;
multiset<one>::iterator it;
int n,m,u,p,x0,h[100005];
one kk[5];
ll la,lb;
bool cmp(one x,one y)
{
if(x.h==y.h)
return h[x.id]<h[y.id];
return x.h<y.h;
}
void solve(int ss,int x)
{
la=0,lb=0;
for(int i=17;i>=0;--i)
{
if(f[i][ss][0]&&la+lb+da[i][ss][0]+db[i][ss][0]<=x)
{
la+=da[i][ss][0];
lb+=db[i][ss][0];
ss=f[i][ss][0];
}
}
return ;
}
int main ()
{
scanf("%d",&n);
one st;
for(int i=1;i<=4;++i)
{
st.id=0;
if(i>2)
{
st.h=Inf;
}
else st.h=-Inf;
s.insert(st);
}
for(int i=1;i<=n;++i)
scanf("%d",&h[i]);
for(int i=n;i>=1;--i)
{
st=(one){h[i],i};
s.insert(st);
it=s.lower_bound(st);
for(int j=1;j<=2;++j)
{
it++;
kk[j].id=(*it).id;
if(kk[j].id)
kk[j].h=abs((*it).h-h[i]);
else kk[j].h=Inf;
}
it--;
it--;
for(int j=3;j<=4;++j)
{
it--;
kk[j].id=(*it).id;
if(kk[j].id)
kk[j].h=abs((*it).h-h[i]);
else kk[j].h=Inf;
}
sort(kk+1,kk+5,cmp);
f[0][i][1]=kk[1].id;
db[0][i][1]=kk[1].h;
f[0][i][0]=kk[2].id;
da[0][i][0]=kk[2].h;
}
for(int k=1;k<=17;++k)
for(int i=1;i<=n;++i)
for(int j=0;j<2;++j)
{
if(k==1)
{
f[1][i][j]=f[0][f[0][i][j]][1-j];
da[1][i][j]=da[0][i][j]+da[0][f[0][i][j]][1-j];
db[1][i][j]=db[0][i][j]+db[0][f[0][i][j]][1-j];
}
else
{
f[k][i][j]=f[k-1][f[k-1][i][j]][j];
da[k][i][j]=da[k-1][i][j]+da[k-1][f[k-1][i][j]][j];
db[k][i][j]=db[k-1][i][j]+db[k-1][f[k-1][i][j]][j];
}
}
scanf("%d",&x0);
scanf("%d",&m);
double ans=(double)Inf,nowans;
p=-1;
for(int i=1;i<=n;++i)
{
solve(i,x0);
if(lb==0)
{
if(p==-1)
p=i;
}
else
{
nowans=(double)la/(double)lb;
if(nowans==ans)
{
if(h[i]>h[p])
p=i;
}
else if(nowans<ans)
{
p=i;
ans=nowans;
}
}
}
printf("%d\n",p);
for(int i=1;i<=m;++i)
{
scanf("%d%d",&p,&x0);
solve(p,x0);
printf("%d %d\n",la,lb);
}
return 0;
}