「GLR-R3」惊蛰

「GLR-R3」 惊蛰

Link

Describe

给定非负整数序列 {an},定义函数 f(x,y)

f(x,y)={xy,xyC,x<y,

其中 C 是给定常数。请构造一个不增非负整数序列 {bn},最小化

i=1nf(bi,ai).

1n106,0ai,C109

Solution

容易想到一个 O(nV) 状态的 DP,定义 g(i,j)bi=j 的最小权值,转移可以通过后缀和的方法 O(1).

g(i,j)=minkjg(i1,k)+f(j,ai)

考虑优化状态,一般对于值域很大的 DP,一般值域状态只有部分有用,大部分可以省去。贪心地考虑,如果 j,biaj 那么存在一个不劣的解 bi 满足 j,bi=aj,我们可以把状态做到 O(n2),记 pkai 中第 k 大的值。

由于我们只要求 g(n) 且转移 g(i) 只与 g(i1) 有关,所以我们可以考虑转移时用线段树维护 g(i) 的值,我们记 G 表示 g 的后缀最小值,用线段树的区间修改代替 O(n) 转移。

考虑具体如何转移,我们要实现以下操作。

  • 对于 pj<ai,加上 C

  • 对于 pjai,加上 pjai

  • 然后滚一个后缀最小值

由于 G 单调不减,对于前两个操作我们可以二分出一个 p,在 [1,p1] 执行第一个操作,[p+1,n] 执行第一个操作。

考虑如何维护第三个操作,因为 G 单调不减,对于 [1,p1] 整体平移,单调性不变,而对于 [p+1,n] 加上的 pjai 也单调不减,所以 [p+1,n] 单调性不变。

所以我们只需要在 [1,p1] 用线段树二分找到第一个满足 g(i,k)g(i,p)k 然后在 [k,p1] 上区间覆盖即可。

所以线段树维护 DP 转移应该是一个优化转移较简单的 DP 的思路。

#include<bits/stdc++.h>
#define lowbit(x) ((x)&-(x))
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define MAXN (1000005)
#define ll long long
using namespace std;
void File()
{
    freopen("C:\\Users\\Administrator\\Desktop\\Code\\IO\\input.txt","r",stdin);
    freopen("C:\\Users\\Administrator\\Desktop\\Code\\IO\\output.txt","w",stdout);
}
template<typename type>
void read(type &x)
{
    x=0;char ch=0;bool f=0;
    while(ch<'0'||ch>'9'){f|=!(ch^'-');ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    x=f?-x:x;
}
template<typename type,typename... Args>
void read(type &t,Args &... args)
{
    read(t);
    read(args...);
}
int n;
int l[MAXN<<2],r[MAXN<<2];
ll C;
ll a[MAXN],val[MAXN],f[MAXN<<2],tag[MAXN<<2],sf[MAXN<<2],cov[MAXN<<2];
void build(int p,int L,int R)
{
    l[p]=L,r[p]=R,cov[p]=-1;
    if(!(L^R)) return;
    int mid=L+R>>1;
    build(ls(p),L,mid);
    build(rs(p),mid+1,R);
}
void upd_cov(int p,ll v)
{
    f[p]=v;
    cov[p]=v,tag[p]=0,sf[p]=0;
}
void upd_sf(int p,ll v)
{
    f[p]+=val[r[p]]*v;
    sf[p]+=v;
}
void upd(int p,ll v)
{
    f[p]+=v;
    tag[p]+=v;
}
void pushdown(int p)
{
    if(~cov[p])
    {
        upd_cov(ls(p),cov[p]);
        upd_cov(rs(p),cov[p]);
        cov[p]=-1;
    }
    if(sf[p])
    {
        upd_sf(ls(p),sf[p]);
        upd_sf(rs(p),sf[p]);
        sf[p]=0;
    }
    if(tag[p])
    {
        upd(ls(p),tag[p]);
        upd(rs(p),tag[p]);
        tag[p]=0;
    }
}
void pushup(int p){f[p]=max(f[ls(p)],f[rs(p)]);}
void cover(int p,int L,int R,ll v)
{
    if(L>R) return;
    int nL=l[p],nR=r[p];
    if(L<=nL&&nR<=R)
    {
        upd_cov(p,v);
        return;
    }
    pushdown(p);
    int mid=nL+nR>>1;
    if(L<=mid) cover(ls(p),L,R,v);
    if(R>mid) cover(rs(p),L,R,v);
    pushup(p);
}
void modify(int p,int L,int R,ll v,bool f)
{
    if(L>R) return;
    int nL=l[p],nR=r[p];
    if(L<=nL&&nR<=R)
    {
        upd(p,v);
        if(f) upd_sf(p,1);
        return;
    }
    pushdown(p);
    int mid=nL+nR>>1;
    if(L<=mid) modify(ls(p),L,R,v,f);
    if(R>mid) modify(rs(p),L,R,v,f);
    pushup(p);
}
ll ask(int p,int x)
{
    int nL=l[p],nR=r[p];
    if(!(nL^nR)) return f[p];
    pushdown(p);
    int mid=nL+nR>>1;ll res;
    if(x<=mid) res=ask(ls(p),x);
    else res=ask(rs(p),x);
    pushup(p);
    return res;
}
int find(int p,int lim,ll v)
{
    int nL=l[p],nR=r[p];
    if(nR<=lim&&f[p]<v) return -1;
    if(!(nL^nR)) return nL;
    int mid=nL+nR>>1;
    pushdown(p);
    ll res=find(ls(p),lim,v);
    if(~res)
    {
        pushup(p);
        return res;
    }
    res=mid<lim?find(rs(p),lim,v):(-1);
    pushup(p);
    return res;
}
int main()
{
    File();
    read(n,C);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        val[i]=a[i];
    }
    sort(val+1,val+n+1);
    build(1,1,n);
    for(int i=1;i<=n;i++)
    {
        int pos=lower_bound(val+1,val+n+1,a[i])-val;
        modify(1,pos+1,n,-a[i],1);
        if(pos<=1) continue;
        modify(1,1,pos-1,C,0);
        ll T=ask(1,pos);
        int t=find(1,pos-1,T);
        if(~t) cover(1,t,pos-1,T);
    }
    printf("%lld",ask(1,1));
}

作者:littlepinkpig

出处:https://www.cnblogs.com/littlepinkpig/p/17806469.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

你可以在这里自定义其他内容

作者:littlepinkpig

出处:https://www.cnblogs.com/littlepinkpig/p/17806469.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   little_pinkpig  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
more_horiz
keyboard_arrow_up light_mode palette
选择主题