제출 #1369560

#제출 시각아이디문제언어결과실행 시간메모리
1369560nikolashamiNafta (COI15_nafta)C++20
100 / 100
556 ms131452 KiB
#include<bits/stdc++.h>
using namespace std;
using ll=long long;

#pragma GCC optimize("O3")
const ll N=2006,inf=1e18;
ll a[N][N],n,m;

ll vs[N][N];
vector<array<ll,2>>okolo(ll i,ll j){
    vector<array<ll,2>>ret;
    if(i-1>=1)ret.push_back({i-1,j});
    if(i+1<=n)ret.push_back({i+1,j});
    if(j-1>=1)ret.push_back({i,j-1});
    if(j+1<=m)ret.push_back({i,j+1});
    return ret;
}

ll C[N][N];
ll fw[N];

void add(ll k,ll x){
    k+=3;
    while(k<N){
        fw[k]+=x;
        k+=k&-k;
    }
}

ll get(ll k){
    ll r=0;k+=3;
    while(k){
        r+=fw[k];
        k-=k&-k;
    }
    return r;
}

void upd(ll l,ll r,ll x){
    if(l>r)return;
    add(l,x);
    add(r+1,-x);
}

vector<array<ll,2>>er[N];
ll f[N][N],cur;

void dnc(ll l,ll r,ll tl,ll tr){
    if(tl>tr)return;
    ll md=(tl+tr)/2,opt=l;
    for(ll i=l;i<=r;++i){
        if(f[i][md-1]+C[i][cur]>f[cur][md]){
            f[cur][md]=f[i][md-1]+C[i][cur];
            opt=i;
        }
    }
    dnc(opt,r,md+1,tr);
    dnc(l,opt,tl,md-1);
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            char c;cin>>c;
            if(c=='.'){a[i][j]=-1;vs[i][j]=1;}
            a[i][j]=c-'0';
        }
    }

    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(vs[i][j])continue;
            ll mn=j,mx=j,sum=0;
            vs[i][j]=1;
            queue<array<ll,2>>qu;
            qu.push({i,j});
            while(qu.size()){
                auto[ii,jj]=qu.front();
                qu.pop();
                sum+=a[ii][jj];
                mn=min(mn,jj);
                mx=max(mx,jj);
                for(auto[iii,jjj]:okolo(ii,jj)){
                    if(vs[iii][jjj])continue;
                    vs[iii][jjj]=1;
                    qu.push({iii,jjj});
                }
            }
            er[mn].push_back({mx,sum});
        }
    }


    n=m;

    for(int i=n;i>=0;--i){
        for(int j=i+1;j<=n;++j){
            C[i][j]=get(j);
        }
        for(auto[r,x]:er[i])
            upd(i,r,x);
    }

    for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j)
            f[i][j]=-inf;


    for(int i=1;i<=n;++i){
        cur=i;
        for(int j=1;j<=i;++j)
        	f[i][j]=f[i-1][j];
        dnc(0,i-1,1,i);
    }

    for(int i=1;i<=n;++i)
        cout<<f[n][i]<<'\n';
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…