BZOJ 4639 博士的选取器

Posted on 2016-10-19 16:39  ziliuziliu  阅读(189)  评论(0编辑  收藏  举报

暴力艹rank1。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 300500
#define inf 2147483647
using namespace std;
int n,limit,a[maxn],pre[maxn][20],lp[maxn],dp[maxn],l=1,r=0,q[maxn];
struct status
{
    int val,id;
}s[maxn];
int read()
{
    char ch;int data=0;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9')
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data;
}
bool cmp(status x,status y)
{
    if (x.val!=y.val) return x.val<y.val;
    return x.id<y.id;
}
void get_lp()
{
    int p=n,ret=0;
    for (register int i=n;i>=1;i--)
    {
        ret-=a[i+1];
        while ((ret+a[p]<=limit) && (p>0))
        {
            ret+=a[p];
            p--;
        }
        lp[i]=p+1;
    }
    for (register int i=1;i<=n;i++)
    {
        if (lp[i]==1)
            lp[i]=0;
    }
}
int ask(int x)
{
    int now=x;
    for (register int e=19;e>=0;e--)
    {
        if (pre[now][e]>=lp[x])
            now=pre[now][e];
    }
    return now;
}
void get_table()
{
    for (register int i=1;i<=n;i++)
    {
        while ((l<=r) && (a[i]>a[q[r]])) r--;
        if (l>r) pre[i][0]=0;else pre[i][0]=q[r];
        q[++r]=i;
    }
}
int main()
{
    n=read();limit=read();
    for (register int i=1;i<=n;i++) {a[i]=read();dp[i]=inf;}
    get_lp();
    get_table();
    for (register int i=1;i<=n;i++)
    {
        int now=pre[i][0],ret=a[i];
        while ((now>=lp[i]) && (now))
        {
            dp[i]=min(dp[now]+ret,dp[i]);
            ret=a[now];now=pre[now][0];
        }
        if (!lp[i]) dp[i]=min(dp[i],ret);
        else dp[i]=min(dp[lp[i]-1]+ret,dp[i]);
    }
    printf("%d\n",dp[n]);
    return 0;
}