我是真的佛了!
把我的代码和题解对拍一年了,还是找不到差异
跪求各位大佬给个出路吧!
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 100100
#define re register
#define INF ~(1ll<<30)
typedef long long ll;
using namespace std;
struct node {
int v,i;
bool operator < (const node& b) const {
return this->v < b.v;
}
} c[MAXN];
ll n,h[MAXN],x00,m,s[MAXN],x[MAXN];
int l[MAXN],r[MAXN],w[MAXN],mid;
ll n0[MAXN],n1[MAXN],d0[MAXN],d1[MAXN];
ll f[MAXN][21],dis0[MAXN][21],dis1[MAXN][21];
ll disa,disb,s0;
int read() {
ll x = 0, f = 0;
char ch = getchar();
while(ch<'0'||ch>'9') f|=ch=='-', ch=getchar();
while(ch>='0'&&ch<='9') {
x = (x<<3) + (x<<1) + (ch-'0');
ch = getchar();
}
return f ? -x : x;
}
void write(int x){
if(x > 9) write(x/10);
putchar(x%10+'0');
}
bool cmp1(int a,int b) {//ab是链表下标,
ll x = abs(c[a].v-c[mid].v);//比较链表中元素和中间点的差值
ll y = abs(c[b].v-c[mid].v);
if(x == y) return c[a].v < c[b].v;
else return x < y;
}
void drive(ll r,ll x,ll& disa,ll& disb){
for(re int j = 20; j >= 0; --j)
if(f[r][j] && (ll)disa+disb+dis0[r][j]+dis1[r][j] <= x){
disa += dis0[r][j];
disb += dis1[r][j];
r = f[r][j];
}
if(n0[r] && disa+disb+dis0[r][0] <= x) disa += dis0[r][0];
}
int main() {
// freopen("data.in","r",stdin);a
// freopen("1081.out","w",stdout);
n = read(), h[0] = -INF;
for(re int i = 1; i <= n; ++i)
h[i] = read(), c[i].v = h[i], c[i].i = i;
x00 = read(), m = read();
for(re int i = 1; i <= m; ++i)
s[i] = read(), x[i] = read();
sort(c+1,c+1+n);
for(re int i = 1; i <= n; ++i)
l[i] = i-1, r[i] = i+1, w[c[i].i] = i;
r[n] = 0, c[0].v = -INF;
for(re int i = 1; i <= n; ++i) {
mid = w[i];
int p[5];
p[1] = l[mid], p[2] = l[p[1]];
p[3] = r[mid], p[4] = r[p[3]];
sort(p+1,p+1+4,cmp1);//排序得到最近和第二近
if(p[2]) {
n0[i] = c[p[2]].i;
d0[i] = abs(c[mid].v-c[p[2]].v);
}
if(p[1]) {
n1[i] = c[p[1]].i;
d1[i] = abs(c[mid].v-c[p[1]].v);
}
if(l[mid]) r[l[mid]] = r[mid];
if(r[mid]) l[r[mid]] = l[mid];
}
for(re int i = 1; i <= n; ++i){
f[i][0] = n1[n0[i]];
dis0[i][0] = d0[i];
dis1[i][0] = d1[n0[i]];
}
for(re int j = 20; j >= 1; --j)
for(re int i = 1; i <= n; ++i){
f[i][j] = f[f[i][j-1]][j-1];
dis0[i][j] = dis0[i][j-1] + dis0[f[i][j-1]][j-1];
dis1[i][j] = dis1[i][j-1] + dis1[f[i][j-1]][j-1];
}
double divmin = 1e19;
for(re int i = 1, flag = 0; i <= n; ++i){
disa = disb = 0;
drive(i,x00,disa,disb);
if(disb==0) continue;
else if(disa*1.0/disb < divmin){
divmin = disa*1.0/disb;
s0 = i;
}
}
write(s0), putchar('\n');
for(re int i = 1; i <= m; ++i){
disa = disb = 0;
drive(s[i],x[i],disa,disb);
write(disa), putchar(' '), write(disb), putchar('\n');
}
return 0;
}