萌新求助,5Pts
查看原帖
萌新求助,5Pts
236929
Monaco楼主2021/8/4 22:16

样例都过,数据只有5分

不仅WA,而且TLE。。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ads(k) (abs(h[i]-(k)))
#define zm(p) (p==inf?0:zm[p])
const int N=1e6+10;const inf=0x3fffffff;
int h[N],n,g[N][2],f[N][23][3];
struct node
{ int id,dt;
  friend bool operator <(node x,node y)
  {
    return x.dt<y.dt;
  }
}ans[7];
void init()
{ set<node>s; //默认从小到大排序 
  set<node> :: iterator  it,il;
  //需要用一个数组g[i][0/1]分别描述离i第1/2近的城市
  //set中存的是高度 需要用数组zm[i]得到城市编号
  s.insert(node{n,h[n]}); h[0]=inf;
  for(int i=n-1;i>0;--i)
  { int mini=inf,tl=0,tl2=0;
    ans[0].dt=inf,ans[1].dt=inf,ans[2].dt=inf,ans[3].dt=inf,ans[4].dt=inf,ans[5].dt=inf;
    it=s.upper_bound(node{i,h[i]}); il=it;
    if(it!=s.end())ans[1]=*it;
    if(it!=s.end()&&(++it)!=s.end())ans[2]=*it;it=il;
    if(it!=s.begin())ans[3]=*(--it);
    if(it!=s.begin())ans[4]=*(--it);
    sort(ans+1,ans+4+1);
    for(int j=1;ans[j].dt!=inf;++j)
    {
      if(tl==0||abs(ans[j].dt-h[i])<mini||((abs(ans[j].dt-h[i])==mini)&&ans[j].dt<h[tl]))
      {
        tl2=tl,tl=ans[j].id,mini=abs(ans[j].dt-h[i]);
      }
      else if(tl2==0||abs(ans[j].dt-h[i])<abs(h[tl2]-h[i])||((abs(ans[j].dt-h[i])==abs(h[tl2]-h[i]))&&ans[j].dt<h[tl]))
      {
        tl2=ans[j].id;
      }
    }
    g[i][0]=tl,g[i][1]=tl2;
    
    s.insert(node{i,h[i]});
  }
  for(int i=n;i>0;--i)
  { if(g[i][0]==0||g[i][1]==0)continue;
    f[i][0][0]=g[g[i][1]][0];
    f[i][0][1]=abs(h[i]-h[g[i][1]]);
    f[i][0][2]=abs(h[f[i][0][0]]-h[g[i][1]]);
    for(int j=1;i+(j<<1)<=n;++j)
    { if(f[i][j-1][0]==0)continue;
      f[i][j][0]=f[f[i][j-1][0]][j-1][0]; 
      if(f[i][j][0]==0)continue;
      f[i][j][1]=f[i][j-1][1]+f[f[i][j-1][0]][j-1][1];
      f[i][j][2]=f[i][j-1][2]+f[f[i][j-1][0]][j-1][2];
    }
  }
}
int main()
{
  int xr,m; //freopen("P1081.in","r",stdin); freopen("P1081.out","w",stdout);
  cin>>n;
  for(int i=1;i<=n;++i)cin>>h[i];
  cin>>xr>>m;
  init(); int ansx=0,ansy=0,t;
  for(int i=1;i<=n;++i)
  { int tl=i,lx=0,ly=0,xi=xr;
    for(int j=20;j>=0;--j)
    { if(f[tl][j][0]==0)continue;
      if(xr-f[tl][j][1]-f[tl][j][2]>=0)
      {
        xr-=f[tl][j][1]+f[tl][j][2];
        lx+=f[tl][j][1],ly+=f[tl][j][2];
        tl=f[tl][j][0];
      }
    }
    if(abs(h[g[tl][1]]-h[tl])<=xr)lx+=abs(h[g[tl][1]]-h[tl]);
    if(ly==0)continue;
    if((ansx==0&&ansy==0)||ansx*ly>ansy*lx||(ansx*ly==ansy*lx&&h[i]>h[t]))
    {
      ansx=lx,ansy=ly,t=i;
    }
    xr=xi;
  }
  printf("%d\n",t);
  for(int i=1;i<=m;++i)
  { int s,x;
    scanf("%d%d",&s,&x);
    int tl=s,lx=0,ly=0,xr=x;
    for(int j=20;j>=0;--j)
    { if(f[tl][j][0]==0)continue;
      if(xr-f[tl][j][1]-f[tl][j][2]>=0)
      {
        xr-=f[tl][j][1]+f[tl][j][2];
        lx+=f[tl][j][1],ly+=f[tl][j][2];
        tl=f[tl][j][0];
      }
    }
    if(abs(h[g[tl][1]]-h[tl])<=xr)lx+=abs(h[g[tl][1]]-h[tl]);
    printf("%d %d\n",lx,ly);
  }
  return 0;
}
2021/8/4 22:16
加载中...