CF1465D Grime Zoo
Description
Currently, XXOC's rap is a string consisting of zeroes, ones, and question marks. Unfortunately, haters gonna hate. They will write $x$ angry comments for every occurrence of subsequence 01 and $y$ angry comments for every occurrence of subsequence 10. You should replace all the question marks with 0 or 1 in such a way that the number of angry comments would be as small as possible.
String $b$ is a subsequence of string $a$, if it can be obtained by removing some characters from $a$. Two occurrences of a subsequence are considered distinct if sets of positions of remaining characters are distinct.
Solution
可以证明当$x < y$时,假如一对问号是1和0,当它们被0和1替换时一定不会使答案变劣
所以当$x<y$时,连续的两个?分别是0和1会达到最优
同理$x > y$时,连续的两个?分别是1和0会达到最优
考虑对一个随机的答案不断进行替换使它更优
那么最优解的一定是:前缀的?全部为1/0,后缀的?全部为0/1
#include<iostream> #include<cstring> #include<cstdio> using namespace std; long long x,y,prec[100005],sufc[100005],pre[100005],suf[100005],ans=1ll<<60,n; char s[100005]; inline int read() { int f=1,w=0; char ch=0; while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar(); return f*w; } int main() { scanf("%s",s+1),x=read(),y=read(),n=strlen(s+1); if(x>y) { swap(x,y); for(int i=1;i<=n;i++) if(s[i]=='0') s[i]='1'; else if(s[i]=='1') s[i]='0'; } for(int i=1;i<=n;i++) if(s[i]=='1') prec[i]=prec[i-1]+1,pre[i]=pre[i-1]+1ll*(i-prec[i])*x; else prec[i]=prec[i-1],pre[i]=pre[i-1]+prec[i]*y; for(int i=n;i;i--) if(s[i]=='0') sufc[i]=sufc[i+1]+1,suf[i]=suf[i+1]+1ll*(n-i+1-sufc[i])*x; else sufc[i]=sufc[i+1],suf[i]=suf[i+1]+sufc[i]*y; for(int i=0;i<=n;i++) ans=min(ans,pre[i]+suf[i+1]+prec[i]*sufc[i+1]*y+1ll*(i-prec[i])*(n-i-sufc[i+1])*x); printf("%lld\n",ans); return 0; }