zoukankan      html  css  js  c++  java
  • CF833B The Bakery(线段树维护dp)

    对于暴力dp来说,对于当前i位置分成j段的答案就是f[l][j-1]+val(l+1,i),对于所有符合条件的答案取一个max

    我们发现暴力会t,并且是取max,想到用线段树维护前一次的dp,这样只要dpk次就能获得答案。

    至于val,其实就是区间修改,对于每个点,他有贡献的区间就是离他相同最近的点到他本身的距离,因此用线段树优化dp

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int N=1e5+10;
    int n,k;
    int a[N];
    int last[N];
    int pre[N];
    struct node{
        int l,r;
        int mx;
        int lazy;
    }tr[N<<2];
    int f[N];
    void pushup(int u){
        tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx);
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]={l,r,0,0};
        }
        else{
            tr[u]={l,r,0,0};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    void rebuild(int u,int l,int r){
        tr[u].lazy=0;
        if(l==r){
            tr[u].mx=f[l];
        }
        else{
            int mid=l+r>>1;
            rebuild(u<<1,l,mid);
            rebuild(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    void pushdown(int u){
        int x=tr[u].lazy;
        tr[u<<1].mx+=x;
        tr[u<<1|1].mx+=x;
        tr[u<<1].lazy+=x;
        tr[u<<1|1].lazy+=x;
        tr[u].lazy=0;
    }
    void modify(int u,int l,int r,int x){
        if(tr[u].l>=l&&tr[u].r<=r){
            tr[u].mx+=1;
            tr[u].lazy+=1;
            return ;
        }
        if(tr[u].lazy){
            pushdown(u);
        }
        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);
    }
    int query(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r){
            return tr[u].mx;
        }
        if(tr[u].lazy)
            pushdown(u);
        int mid=tr[u].l+tr[u].r>>1;
        int ans=0;
        if(l<=mid){
            ans=query(u<<1,l,r);
        }
        if(r>mid)
            ans=max(ans,query(u<<1|1,l,r));
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>k;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
            pre[i]=last[a[i]];
            last[a[i]]=i;
        }
        build(1,0,n);
        for(i=1;i<=k;i++){
            rebuild(1,0,n);
            for(int j=i;j<=n;j++){
                modify(1,pre[j],j-1,1);
                f[j]=query(1,0,j-1);
            }
        }
        cout<<f[n]<<endl;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    [ USACO 2018 OPEN ] Out of Sorts (Platinum)
    [ USACO 2018 OPEN ] Out of Sorts (Gold)
    [ USACO 2018 OPEN ] Out of Sorts (Silver)
    [ BZOJ 4236 ] JOIOJI
    [ HAOI 2012 ] 容易题
    [ HAOI 2008 ] 玩具取名
    「BZOJ 4502」串
    Codeforces 493 E.Devu and Birthday Celebration
    「TJOI 2018」教科书般的亵渎
    「TJOI 2018」游园会 Party
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13849536.html
Copyright © 2011-2022 走看看