[bzoj4094]Optimal Milking

建立线段树,维护区间左端点选/不选,右端点选/不选且不含有相邻两个同时选的最大值,合并时注意细节即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mid (l+r>>1)
 4 #define L (k<<1)
 5 #define R (L+1)
 6 int n,m,x,y;
 7 long long ans;
 8 struct ji{
 9     int a[4];
10 }f[200005];
11 ji up(ji x,ji y){
12     ji z;
13     for(int i=0;i<4;i++)z.a[i]=0;
14     for(int i=0;i<4;i++)
15         for(int j=0;j<4;j++)
16             if ((i%2)||(j/2))
17                 z.a[i/2*2+j%2]=max(z.a[i/2*2+j%2],x.a[i]+y.a[j]);
18     return z;
19 } 
20 void update(int k,int l,int r,int x,int y){
21     if (l==r){
22         f[k].a[0]=y;
23         return;
24     }
25     if (x<=mid)update(L,l,mid,x,y);
26     else update(R,mid+1,r,x,y);
27     f[k]=up(f[L],f[R]); 
28 }
29 int main(){
30     scanf("%d%d",&n,&m);
31     for(int i=1;i<=n;i++){
32         scanf("%d",&x);
33         update(1,1,n,i,x);
34     }
35     for(int i=1;i<=m;i++){
36         scanf("%d%d",&x,&y);
37         update(1,1,n,x,y);
38         ans+=f[1].a[0];
39     }
40     printf("%lld",ans);
41 } 
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11265720.html