3897: Power

题解:

首先很贪心的选择

有最大的我们一定会用最大的

然后可以将序列分割。。

就变成了一道模拟题了。。

每个状态记录(h,t,h-have,t-need)

注意一下细节就可以了

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rint register ll 
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
const ll N=6e5;
ll e,r,n;
ll bz[20][N],bz2[20][N],ans,a[N];
ll get_max(ll x,ll y)
{
  ll k=log2(y-x+1);
  if (bz[k][x]>bz[k][y-(1<<k)+1]) return(bz2[k][x]);
  else return(bz2[k][y-(1<<k)+1]);
}
void fz(ll x,ll y,ll pre,ll nxt)
{
  if (x>y) return;
  ll kk=get_max(x,y);
  if ((y-kk+1)*r>=nxt) 
  {
    fz(kk+1,y,r,nxt);
    if ((pre+(kk-x)*r)>=e)
    { 
      ans+=e*a[kk];
      fz(x,kk-1,pre,e);
    }
    else ans+=(pre+(kk-x)*r)*a[kk];
  } else
  {
    if (pre+(kk-x)*r>=e) ans+=(e-(nxt-(y-kk+1)*r))*a[kk],fz(x,kk-1,pre,e);
    else ans+=((y-x+1)*r+pre-nxt)*a[kk];
  }
}
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  ios::sync_with_stdio(false);
  ll T;
  cin>>T;
  rep(tt,1,T)
  {
    cin>>e>>r>>n; ans=0;
    me(bz); me(bz2);
    rep(i,1,n) cin>>bz[0][i],bz2[0][i]=i,a[i]=bz[0][i];
    for (ll i=1;i<=19;i++)
      for (ll j=1;j<=n;j++)
        if (bz[i-1][j]>bz[i-1][j+(1<<(i-1))])
          bz[i][j]=bz[i-1][j],bz2[i][j]=bz2[i-1][j];
        else bz[i][j]=bz[i-1][j+(1<<(i-1))],bz2[i][j]=bz2[i-1][j+(1<<(i-1))]; 
    fz(1,n,e,0);
    cout<<ans<<endl;
  }
  return 0;
}

 

posted @ 2018-07-09 16:03  尹吴潇  阅读(150)  评论(0编辑  收藏  举报