zoukankan      html  css  js  c++  java
  • CF1304F Animal Observation(线段树+dp)

    虽然题目说着分两种类型,其实就是相当于对于每一行,选择一个矩形去框

    那么这样就统一了形式,而我们发现,每一行只跟上一行相关。

    还有一个问题是交叉部分的去重,我们发现这有三种情况,因此对于三种情况分别讨论

    但是枚举更新复杂度太高,因此想到优化,这种优化比较套路,用线段树求区间最大值就行

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e5+10;
    const int mod=1e9+7;
    const ll inf=1e12;
    int n,m,k;
    int a[55][20200];
    ll sum[55][20200];
    ll f[20200];
    struct node{
        int l,r;
        ll mx;
    };
    struct Tree{
        node tr[N<<2];
        void build(int u,int l,int r){
            if(l==r){
                tr[u]={l,r,-inf};
            }
            else{
                tr[u]={l,r};
                int mid=l+r>>1;
                build(u<<1,l,mid);
                build(u<<1|1,mid+1,r);
                pushup(u);
            }
        }
        void pushup(int u){
            tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx);
        }
        void modify(int u,int l,int r,ll x){
            if(tr[u].l>=l&&tr[u].r<=r){
                tr[u].mx=x;
                return ;
            }
            int mid=tr[u].l+tr[u].r>>1;
            if(l<=mid)
                modify(u<<1,l,r,x);
            if(r>mid)
                modify(u<<1|1,l,r,x);
            pushup(u);
        }
        ll query(int u,int l,int r){
            if(l>r)
                return -1e12;
            if(tr[u].l>=l&&tr[u].r<=r){
                return tr[u].mx;
            }
            int mid=tr[u].l+tr[u].r>>1;
            ll ans=-1e12;
            if(l<=mid)
                ans=max(ans,query(u<<1,l,r));
            if(r>mid)
                ans=max(ans,query(u<<1|1,l,r));
            return ans;
        }
    }T[5];
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m>>k;
        int i,j;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                cin>>a[i][j];
                sum[i][j]=sum[i][j-1]+a[i][j];
            }
        }
        T[1].build(1,1,m+10);
        T[2].build(1,1,m+10);
        T[3].build(1,1,m+10);
        for(i=1;i<=n;i++){
            for(j=1;j+k-1<=m;j++){
                f[j]=max(T[3].query(1,1,j-k),T[3].query(1,j+k,m));
                f[j]=max(f[j],T[1].query(1,j-k+1,j)+sum[i][j-1]);
                f[j]=max(f[j],T[2].query(1,j+1,j+k)-sum[i][j+k-1]);
                f[j]=max(f[j],0ll);
            }
            for(j=1;j+k-1<=m;j++){
                f[j]+=(sum[i][j+k-1]-sum[i][j-1]);
                f[j]+=(sum[i+1][j+k-1]-sum[i+1][j-1]);
                T[1].modify(1,j,j,f[j]-sum[i+1][j+k-1]);
                T[2].modify(1,j,j,f[j]+sum[i+1][j-1]);
                T[3].modify(1,j,j,f[j]);
            }
        }
        cout<<T[3].query(1,1,m)<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    ios中的几种多线程实现
    在mac下使用终端管理svn
    关于UIScrollViewDelegate协议中每个回调函数的意义及执行顺序的理解
    UIView 及其子类对象 抖动效果的实现
    ios、andriod、cocos2d 视图层次理解
    委托  通知中心   监听/观察
    iphone 中使用苹果禁用的私有Framework
    关于苹果官方网站Reachability检测网络的总结
    iOS设备的分辨率
    ios开发多线程、网络请求的理解 错误码的理解
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14386475.html
Copyright © 2011-2022 走看看