小红的数组操作
题意:
初始有一个全黑的数组,可以染一段前缀和一段后缀为红,求让黑数组中元素不重的最小代价
思路:
枚举染的前缀,通过双指针预处理最长的合法序列,那么后缀染的起始点一定要在在序列末尾的前面,通过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;
}

浙公网安备 33010602011771号