Codeforces Global Round 4 B. WOW Factor (字首和,數學)
阿新 • • 發佈:2020-10-14
-
題意:找出序列中有多少子序列是\(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; }