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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14386475.html
Copyright © 2011-2022 走看看