Codeforces Global Round 4 B. WOW Factor (前缀和,数学)

-
题意:找出序列中有多少子序列是\(wow\),但是\(w\)只能用\(vv\)来表示.
-
题解:我们分别记录连续的\(v\)和\(o\)的个数,用\(v1\)和\(v2\)存,这里要注意前导\(o\)不能要,观察一下写出答案公式:\(ans=v1[i]*(v2[i]*(v1[i+1]+...+v1[k])+v2[i+1]*(v1[i+2]+...+v1[k])+...+v2[k-1]*v[k])+v1[i+1]*(...)+...+v1[k-1]*v2[k-1]*v1[k]\),很显然我们是不能直接算的,但是发现这个公式里面有很多连续的线性和,所以我们可以用前缀和来进行复杂度的优化,将其降到\(O(n)\).
-
代码:
string s; vector<ll> v1,v2; ll cnt1,cnt2; ll pre1[N],pre[N]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>s; bool flag=false; for(int i=0;i<(int)s.size();++i){ if(s[i]=='v'){ cnt1++; if(cnt2 && flag){ v2.pb(cnt2); cnt2=0; } if(!flag) cnt2=0; flag=true; } else{ cnt2++; if(cnt1){ v1.pb(cnt1); cnt1=0; } } } if(cnt1) v1.pb(cnt1); int len1=(int) v1.size(); int len2=(int) v2.size(); for(int i=len1-1;i>=0;--i){ pre1[i]=pre1[i+1]+v1[i]-1; //先对v1求前缀和. } for(int i=len2-1;i>=0;--i){ pre[i]=pre[i+1]+v2[i]*pre1[i+1]; //求出v2[i]*(v1[i+1]+...+v1[k])的前缀和pre[i]<-这里(...)的就是我们上一步求的前缀和pre1[i+1]. } ll ans=0; for(int i=0;i<len1;++i){ ans+=(v1[i]-1)*pre[i]; } cout<<ans<<endl; return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号