小红的数组操作

小红的数组操作

题意:

初始有一个全黑的数组,可以染一段前缀和一段后缀为红,求让黑数组中元素不重的最小代价

思路:

枚举染的前缀,通过双指针预处理最长的合法序列,那么后缀染的起始点一定要在在序列末尾的前面,通过ST表预处理出这段的后缀最小值

`int f[maxn][31];
int n;
void init(vector<int>&suf){
    memset(f,inf,sizeof inf);
    rep(i,1,n+1)f[i][0]=suf[i];

    for(int j=1;j<=30;j++){
        for(int i=1;i+(1<<j)-1<=n+1;i++){
            f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);
        }
    }
}
int ask(int l,int r){
    int k=log2(r-l+1);
    return min(f[l][k],f[r-(1<<k)+1][k]);
}

void solve(){
    cin>>n;
    
    vector<int>a(n+2);
    rep(i,1,n)cin>>a[i];
    vector<int>k(n+2);
    int j=1;
    map<int,int>mp;

    for(int i=0;i<=n+1;i++){
        while(j<=n&&mp[a[j]]==0){
            mp[a[j]]++;j++;
        }
        k[i]=j;
        if(i)mp[a[i]]--;
    }
    
    int ans=llmax;
    vector<int>suf(n+2);
    for(int i=n;i>=1;i--)suf[i]=a[i]*(n-i+1);
    init(suf);

    rep(i,1,n+1){
        ans=min(ans,(i-1)*a[i-1]+ask(i,k[i]));
        // debug(k[i]);
        // debug(ask(i,k[i]));
    }

    cout<<ans<<endl;
}
posted @ 2025-06-16 16:10  Marinaco  阅读(21)  评论(0)    收藏  举报
//雪花飘落效果