Codeforces 1304F2 Animal Observation (hard version) 代码(dp滑动窗口线段树区间更新优化)

https://codeforces.com/contest/1304/problem/F2

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 4e4+5;
 4 int dp[55][maxn];
 5 int val[55][maxn];
 6 int sum[55][maxn];
 7 int n,m,k;
 8 struct node{
 9     int l,r;
10     int Max,lz;
11 }seg_t[maxn*4];
12 void build(int l,int r,int p){
13     seg_t[p].l = l,seg_t[p].r = r;
14     if(l == r) {
15         seg_t[p].Max = 0;return ;
16     }
17     int mid = (l+r)>>1;
18     build(l,mid,p*2);
19     build(mid+1,r,p*2+1);
20     seg_t[p].Max = max(seg_t[p*2].Max ,seg_t[p*2+1].Max );
21 }
22 void pushdown(int k){
23     seg_t[k*2].lz +=seg_t[k].lz ;
24     seg_t[k*2+1].lz +=seg_t[k].lz ;
25     seg_t[k*2].Max +=seg_t[k].lz ;
26     seg_t[k*2+1].Max +=seg_t[k].lz ;
27     seg_t[k].lz = 0; 
28 }
29 void upd(int L,int R,int p,int v){
30     if(seg_t[p].l == L && seg_t[p].r == R){
31         seg_t[p].lz +=v;
32         seg_t[p].Max +=v;
33         return;
34     }
35     if(seg_t[p].lz ) pushdown(p);
36     int mid = (seg_t[p].l + seg_t[p].r )>>1;
37     if(R<=mid) upd(L,R,p*2,v);
38     else if(L>mid) upd(L,R,p*2+1,v);
39     else{
40         upd(L,mid,p*2,v);
41         upd(mid+1,R,p*2+1,v);
42     }
43     seg_t[p].Max = max(seg_t[p*2].Max ,seg_t[p*2+1].Max );
44 }
45 int query(int p,int L,int R){
46     if(seg_t[p].l == L && seg_t[p].r == R) return seg_t[p].Max ;
47     if(seg_t[p].lz ) pushdown(p);
48     int mid = (seg_t[p].l +seg_t[p].r)>>1;
49     if(R<=mid) return query(p*2,L,R);
50     else if(L>mid) return query(p*2+1,L,R);
51     else return max(query(p*2,L,mid),query(p*2+1,mid+1,R)); 
52 }
53 int main(){
54     cin>>n>>m>>k;
55     for(int i = 1;i<=n;i++){
56         for(int j = 1;j<=m;j++) {
57             cin>>val[i][j];
58             sum[i][j] = sum[i][j-1] + val[i][j];
59         }
60     }
61     for(int i = 1;i<=m-k+1;i++){
62         dp[1][i] = sum[1][i+k-1] - sum[1][i-1]+sum[2][i+k-1]-sum[2][i-1];
63     }
64     for(int i = 2;i<=n;i++){
65         memset(seg_t,0,sizeof(seg_t));
66         build(1,2*m,1);
67         for(int j = 1;j<=m;j++) upd(j,j,1,dp[i-1][j]);
68         for(int j = 1;j<=k;j++) upd(1,j,1,-val[i][j]);
69         for(int j = 1;j<=m-k+1;j++){
70             dp[i][j] = max(dp[i][j],query(1,1,m)+sum[i][j+k-1]-sum[i][j-1]+sum[i+1][j+k-1]-sum[i+1][j-1]);
71             upd(max(1,j-k+1),j,1,val[i][j]);
72             upd(j+1,j+k,1,-val[i][j+k]);
73         }
74     } 
75     int ans = 0;
76     for(int i = 1;i<=m;i++) ans = max(ans,dp[n][i]);
77     cout<<ans;
78     return 0;
79 }
View Code

 

posted @ 2020-02-24 17:26  AaronChang  阅读(159)  评论(0编辑  收藏  举报