阿宁被鉴定成毒瘤出题人。
一个长度为n且仅有小写字母的字符串s,阿宁的毒瘤程度为s串的"udu"子序列的个数。
现在阿宁痛心疾首,想降低毒瘤程度。
阿宁想修改其中s串的一个字符(也可以不修改。只能修改成小写字母),需要修改后毒瘤程度最小。
子序列:指按照原串的顺序取一些字符,组成新的字符串。例如"dudu"、"udu"是"dudovoudu"的子序列,而"uudd"、"abc"不是。
阿宁想知道修改后的s是什么?输入描述:
一个仅包含小写字母的字符串s。 1≤len(s)≤2×105输出描述:
输出修改后的s串。 如果答案有多个,输出任意一解即可。示例1
输入
dudovoudu输出
dddovoudu说明
"dudovoudu"有4个"udu"子序列,分别是s2s3s7,s2s3s9,s2s8s9,s7s8s9 "dddovoudu"有1个"udu"子序列,是s7s8s9
正反遍历
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
char s[200007];
ll f1[200007],f2[200007],f3[200007],f4[200007];
int main(){
scanf("%s",s+1);
ll len=strlen(s+1);
for(int i=1;i<=len;i++){
f1[i]=f1[i-1];
f2[i]=f2[i-1];
if(s[i]=='u'){
f1[i]++;
}
else if(s[i]=='d'){
f2[i]+=f1[i];
}
}
ll op=len;
ll mamx=0;
for(ll i=len;i>=1;i--){
f3[i]=f3[i+1];
f4[i]=f4[i+1];
if(s[i]=='u'){
if(f4[i+1]+f2[i-1]>mamx){
mamx=f4[i+1]+f2[i-1];
op=i;
}
f3[i]++;
}
else if(s[i]=='d'){
if(f3[i+1]*f1[i-1]>mamx){
mamx=f3[i+1]*f1[i-1];
op=i;
}
f4[i]+=f3[i];
}
}
s[op]='a';
for(int i=1;i<=len;i++){
printf("%c",s[i]);
}
}