BZOJ-4094: [Usaco2013 Dec]Optimal Milking

[文章目录]

Description

Farmer John最近购买了N(1 <= N <= 40000)台挤奶机,编号为1 ... N,并排成一行。第i台挤奶机每天能够挤M(i)单位的牛奶 (1 < =M(i) <=100,000)。由于机器间距离太近,使得两台相邻的机器不能在同一天使用。Farmer John可以自由选择不同的机器集合在不同的日子进行挤奶。在D(1 < = D < = 50,000)天中,每天Farmer John对某一台挤奶机进行维护,改变该挤奶机的产量。Farmer John希望设计一个挤奶方案,使得挤奶机能够在D天后获取最多的牛奶。

线段树维护区间两端点是否选择的最大挤奶产量即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,w[41000];
int t[161000][4];// 0:00 1:01 2:10 3:11
void pushup(int pos)
{
    t[pos][0]=max(t[pos<<1][1]+t[pos<<1|1][0],max(t[pos<<1][0]+t[pos<<1|1][2],t[pos<<1][0]+t[pos<<1|1][0]));
    t[pos][1]=max(t[pos<<1][0]+t[pos<<1|1][1],max(t[pos<<1][0]+t[pos<<1|1][3],t[pos<<1][1]+t[pos<<1|1][1]));
    t[pos][2]=max(t[pos<<1][2]+t[pos<<1|1][0],max(t[pos<<1][2]+t[pos<<1|1][2],t[pos<<1][3]+t[pos<<1|1][0]));
    t[pos][3]=max(t[pos<<1][2]+t[pos<<1|1][1],max(t[pos<<1][2]+t[pos<<1|1][3],t[pos<<1][3]+t[pos<<1|1][1]));
}
void build(int pos,int l,int r)
{
    if(l==r)
    {
        t[pos][3]=w[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(pos<<1,l,mid); build(pos<<1|1,mid+1,r);
    pushup(pos);
}
void fix(int pos,int l,int r,int x,int y)
{
    if(l==r)
    {
        t[pos][3]=y;
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid) fix(pos<<1,l,mid,x,y);
    else fix(pos<<1|1,mid+1,r,x,y);
    pushup(pos);
}
long long ans;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i) scanf("%d",w+i);
    build(1,1,n); int x,y;
    while(m--)
    {
        scanf("%d%d",&x,&y);
        fix(1,1,n,x,y);
        ans+=max(max(t[1][0],t[1][1]),max(t[1][2],t[1][3]));
    }
    printf("%lld",ans);
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注