bzoj 4094: [Usaco2013 Dec]Optimal Milking

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天后获取最多的牛奶。

Input

第1行:两个整数N和D
第2..N+1行:每台挤奶机的M(i)
第N+2..N+D+1行:两个整数i和m,表示每天对机器i进行维护,机器i的产量为m。

Output

最大产量

Sample Input

5 3
1
2
3
4
5
5 2
2 7
1 10

Sample Output

32
【样例解释】
第1天,最优方案为2+4=6 ( 方案1+3+2一样)
第2天,最优方案为7+4=11
第3天,最优方案为10+3+2=15

Source

Gold

题解:

线段树。。

没什么好说的。。

发四种情况讨论

1.两边都选

2.左选右不选

3.左不选右选

4.都不选

 

#include<stdio.h>
#include<iostream>
using namespace std;
const int N=40005;
#define p1 (p<<1)
#define p2 (p<<1|1)
int n,m,i,x,y,a[N],t[N<<2][4];
long long ans;
inline void read(int&a){
    char c;
    while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';
    while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
}
void pushup(int p)
{
    t[p][0]=t[p][1]=t[p][2]=t[p][3]=0;
    if(t[p1][0]!=-1&&t[p2][2]!=-1) t[p][0]=t[p1][0]+t[p2][2];
    if(t[p1][1]!=-1&&max(t[p2][0],t[p2][2])!=-1) t[p][0]=max(t[p][0],t[p1][1]+max(t[p2][0],t[p2][2]));
    if(t[p1][0]!=-1&&t[p2][3]!=-1) t[p][1]=t[p1][0]+t[p2][3];
    if(t[p1][1]!=-1&&max(t[p2][1],t[p2][3])!=-1) t[p][1]=max(t[p][1],t[p1][1]+max(t[p2][1],t[p2][3]));
    if(t[p1][2]!=-1&&t[p2][2]!=-1) t[p][2]=t[p1][2]+t[p2][2];
    if(t[p1][3]!=-1&&max(t[p2][0],t[p2][2])!=-1) t[p][2]=max(t[p][2],t[p1][3]+max(t[p2][0],t[p2][2]));
    if(t[p1][2]!=-1&&t[p2][3]!=-1) t[p][3]=t[p1][2]+t[p2][3];
    if(t[p1][3]!=-1&&max(t[p2][1],t[p2][3])!=-1) t[p][3]=max(t[p][3],t[p1][3]+max(t[p2][1],t[p2][3]));
}
void build(int l,int r,int p)
{
    if(l==r)
    {
        t[p][0]=a[l];
        t[p][3]=0;t[p][1]=t[p][2]=-1;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,p1);build(mid+1,r,p2);
    pushup(p);
}
void update(int l,int r,int x,int y,int p)
{
    if(l==r) 
    {
        t[p][0]=y;
        return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) update(l,mid,x,y,p1);else update(mid+1,r,x,y,p2);
    pushup(p);
}
int main()
{
    read(n),read(m);
    for(i=1;i<=n;i++) read(a[i]);
    build(1,n,1);
    while(m--)
    {
        read(x),read(y);
        update(1,n,x,y,1);
        ans+=max(max(t[1][0],t[1][1]),max(t[1][2],t[1][3]));
    }
    cout<<ans;
    return 0;
}

 

  

 

 

posted @ 2016-08-20 19:32  lwq12138  阅读(230)  评论(0编辑  收藏  举报