Codeforces805D. Minimum number of steps
题目意思就是给你一个字符串然后每个ab要变bba,然后问你最少变化多少次。
不管怎么变最后的字符串都是变成了bbbbbb....aaaaaa这种形式,a移到了最右,b移到了最左,可以知道不管怎么变,变化次数都是一样的,因为每个a后面直接相连的b的个数就是其对应的变化次数。所以问题的求解变化次数的关键就是要维护每个a后面直接相连的b的个数了,假如我们从前往后找a然后统计其后面直接相连b的个数,记a后面b的个数为cntb,那么对应的abbb..这样的序列的变化次数就是cntb,当这个a是最后一个a时,这个cntb的确就是变化次数,但是如果一旦这个a后面还有a,且这个a后面也跟着b的话,第二个a,一变化变成bbb..a这种样子,我们以为处理好的第一个a后面又出现了b,又可以变化了,这样子又要对第一个a处理一次,而且第1个a后面不只有一个a,所以对第一个a的可能需要重复处理多次,这样就很麻烦了,所以可以从尾往前处理,这样就可以保证每处理一个a,其后面就不会在存在b了,因为可以发现这样处理的话,每处理完一个a,这个a都要移动到最右,这样处理就方便多了,还要注意一个cntb可能会爆long long,可以对其取模
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
int main()
{
ll len,cntb=0,ans=0;
string s;
cin>>s;
len=s.size();
for(int i=len-1;i>=0;i--)
{
if(s[i]=='a')
ans=(ans+cntb)%mod,cntb*=2,cntb%=mod;//因为(ans+cntb)%mod=(ans%mod+cntb%mod)%mod,每次cntb翻倍后取模相当于是提前进行了取模操作,对ans的结果没有影响。
else
cntb++;
}
cout<<ans<<endl;
return 0;
}