4094: [Usaco2013 Dec]Optimal Milking
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 121 Solved: 91
[Submit][Status][Discuss]
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
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
【样例解释】
第1天,最优方案为2+4=6 ( 方案1+3+2一样)
第2天,最优方案为7+4=11
第3天,最优方案为10+3+2=15
自己瞎YY了一个鬼畜 想不出来 翻题解。。。
线段树维护左、右不选、两边都不选、两边都选
暴力维护
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
inline void print(ll x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=40100;
int a[N];
struct seg_tree{int mx,usel,user,sparer,sparel,use,spare;}tr[N<<2];
inline void pushup(int k)
{
tr[k].sparel=tr[k<<1].spare+tr[k<<1|1].mx;
tr[k].sparel=max(tr[k].sparel,tr[k<<1].sparel+tr[k<<1|1].sparel);
tr[k].sparer=tr[k<<1|1].spare+tr[k<<1].mx;
tr[k].sparer=max(tr[k].sparer,tr[k<<1].sparer+tr[k<<1|1].sparer);
tr[k].use=max(tr[k<<1].mx+tr[k<<1|1].sparel,tr[k<<1|1].mx+tr[k<<1].sparer);
tr[k].spare=max(tr[k<<1].sparel+tr[k<<1|1].spare,tr[k<<1|1].sparer+tr[k<<1].spare);
tr[k].spare=max(tr[k].spare,tr[k<<1].spare+tr[k<<1|1].spare);
tr[k].mx=max(tr[k].use,tr[k].spare);
tr[k].mx=max(tr[k].sparer,tr[k].mx);tr[k].mx=max(tr[k].sparel,tr[k].mx);
}
void build(int k,int l,int r)
{
if(l==r)
{tr[k].mx=tr[k].use=a[l];tr[k].sparer=tr[k].sparel=tr[k].spare=0;return ;}
int mid=l+r>>1;
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int x,int val)
{
if(l==r)
{tr[k].mx=tr[k].use=val;return ;}
int mid=l+r>>1;
if(mid<x)modify(k<<1|1,mid+1,r,x,val);
else modify(k<<1,l,mid,x,val);
pushup(k);
}
int main()
{
int n=read(),d=read();
register int i,x,y;ll ans=0;
for(i=1;i<=n;++i)a[i]=read();
build(1,1,n);
while(d--)
{
x=read();y=read();
modify(1,1,n,x,y);
ans+=tr[1].mx;
}
print(ans);puts("");
return 0;
}
/*
5 3
1
2
3
4
5
5 2
2 7
1 10
32
*/