zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    PHP数字签名算法
    PHP日期相关类
    浏览器常见bug及解决办法
    PHPer整理的前端开发知识
    小程序之轮播图(2020.4.13更新)
    Android APK反编译 apktool使用教程
    秒懂-单列布局水平居中布局
    一句话搞定-phpStudy安装yaf扩展
    Git的简单安装
    人人都能读懂的css3 3d小demo
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12357797.html
Copyright © 2011-2022 走看看