×

# ABREPEAT - Editorial

Author: Kamil Debowski
Primary Tester: Marek Sokołowski
Secondary Tester: Praveen Dhinwa
Editorialist: Praveen Dhinwa

simple

combinatorics

# PROBLEM:

You are provided a string $s$ of length $N$. Suppose $t$ be the string formed by concatenating the string $s$ $K$ times, i.e. $t = s + s + \dots + s$ ($K$ times). We want to find the number of occurrences of subsequence "ab" in it.

# Finding number of subsequences "ab" in a given string $s$.

Finding number of subsequences "ab" in a given string $s$ is same as finding number of pair of indices $(i, j), i < j$ such that $s_i$ = 'a' and $s_j$ = 'b'. The brute force way of iterating over all such pairs of indices $i, j$ and checking the conditions $s_i$ = 'a' and $s_j$ = 'b' would be $\mathcal{O}({|s|}^2)$.

However, you can do better. In fact, you can find this in a single pass over the string in $\mathcal{O}(|s|)$ time. Consider an index $j$ such that $s_j$ = 'b', suppose we want to find number of $i$'s such that $i < j$ and $s_i =$ 'a'. It will be same as number of occurrences of character 'a' till position $j$. We can maintain the count of a's by iterating over the array from left to right. This way, we will be able to find the answer in single iteration over the string $s$ in $\mathcal{O}(|s|)$ time. Pseudo code follows.

cnta = 0;
ans = 0;
for i = 1 to |s|:
if s[i] == a:
cnta++;
if s[i] == b:
ans += cnta;


# Can we use this idea directly?

Now we construct the string $t$ and find the number of subsequences "ab" in it in $\mathcal{O}(|t|)$ time, which will be $\mathcal{O}(N \cdot K)$. Constraints of the problem say that $N \cdot K$ could go up to $10^9$. So, this won't work in time.

# Towards a counting based solution idea.

Let $t = s_1 + s_2 + s_3 + \dots + s_K$, where $s_i = s$. We call $s_i$ the $i$-th occurrence of string $s$.

Let us view the occurrences of subsequence "ab" in $t$ as follows. One of the below two cases can happen.

• "ab" lies strictly inside some occurrence of string $s$ in $t$, i.e. "ab" lies strictly inside some $s_i$. We can find the number of occurrences of "ab" in $s$. Let us denote it by $C$. The total number of occurrences "ab" in this case will be $C \cdot K$.

• In the other case, "a" lies inside some string $s_i$, whereas "b" lies in some other string $s_j$ such that $i < j$. Finding the number of occurrences of "ab" in this case will be same as choosing the two strings $s_i, s_j$ ($\binom{K}{2}$ ways), and multiplying it by the number of occurrences of "a" in $s_i$ (denote by $cnt_a$) and the number of occurrences of "b" in $s_j$ (denote by $cnt_b$), i.e. $\binom{K}{2} \cdot cnt_a \cdot cnt_b$. As $s_i = s$, $cnt_a$ will be number of occurrences of "a" in $s$ and $cnt_b$ will be the number of occurrences of "b" in $s$.

We can find $C, cnt_a, cnt_b$ in $\mathcal{O}(N)$ time. Thus, overall time complexity of this approach is $\mathcal{O}(N)$ which will easily pass in time for $N \leq 10^5$. Pseudo code follows.

cnta = 0
cntb = 0;
C = 0;
for i = 1 to N:
if s[i] == 'a':
cnta++;
if s[i] == 'b':
cntb++;
C += cnta;
// First case, i.e. "ab" lies strictly inside some occurences of s, i.e. s_i in t
ans = C * K
// The other case, i.e. "a" lies inside some string s_i, where as "b" lies in other string s_j such that i < j
ans += K * (K - 1) / 2 * cnta * cntb ;


# AUTHOR'S AND TESTER'S SOLUTIONS:

This question is marked "community wiki".

2.5k53137170
accept rate: 20%

19.8k350498541

 1 If I am not wrong, then c is denoting the number of 'ab' sequences in original string. Your example is very well correct. Your applied concept is correct for that category of test case. But again, that's just one of the many categories. You stated that " C here will act as both common diff as well as the first term." . This is wrong. This is a property of this particular string. The common difference actually is number of 'b' in the string, and since here number of 'b' is equal to number of 'ab', you see the equality. Also, there are some tricky categories of test cases. One of the categories of the test case are the ones with no 'ab' sequence in original string. Consider string "ba" repeated twice, giving "baba". Now your c is 0. So if your formula has a multiplication with c, it will give a result 0. I ran your code for this test case- Input 1 3 2 baa Output 1  While I didn't debug your code (too many variables, made it confusing to see which variable is doing what), I saw that your program prints 1 (if k=2) for strings like "baaa" "baaaaaaa" &etc. I think this will help you find the flaw in logic/code. What I meant when I said there is an AP perspective, is that, look at the final string. Let s="aba" and k=3. Final string (say p) is p= "abaabaaba" For the very first a in s. It is used to form 1 ab. Also, we can say that p is formed of "aba aba aba" (I inserted a space between repetitions intentionally for clarity). Now look at the starting a of all 3 "aba" and find number of ab subsequence using that particular 'a' For 'a' at index 0, ab seq= 3. For 'a' at index 3, ab seq=2, For 'a' at index 6, ab seq=1.  I meant that this is an forming an AP. Similarly then I look at 'ab' s formed by every 'a' present in the string, and sum them up to get the final answer. See that it covers all 'a' and hence every possible 'ab' is covered, giving correct answer. Some observation and playing with cases/random samples would yield common difference= Number of b in string s, and a= number of ab formed in s by that particular a. Then we can safely apply the AP sum formula to find the answer. answered 24 Apr '17, 21:41 15.4k●1●20●66 accept rate: 18% Wow! Thanks man! You are really a great person @vijju123 :) Actually the test cases which you gave cleared it all. Again Thanks :) I am really sorry for being so silly. (24 Apr '17, 21:48) 1 I am glad it helped dear :) (24 Apr '17, 21:52)
 1 @pro1992 If x be the no. of sub-sequence of ab found in s then for each of the k strings would have x no. of sub-sequence ab. and it will contribute total of k*x in final answer. coming to the second part. now we will consider if we chose 'a' from some string i and 'b' for some string j. suppose we chose 'a' from the first string then we have cntA choice for picking up 'a' and cntB*(k-1) choice for picking up 'b' so total pairs of 'ab' would be cntA*[cntB*(k-1)] similarly if we choose 'a' from the second string then we will have cntB*(k-2) choice for picking 'b' and total 'ab' pairs in this case would be cntA*[cntB*(k-2)] and so on. The final equation will look like: ans = cntA*cntB*(k-1)+cntA*cntB*(k-2)+cntA*cntB*(k-3)+...+cntA*cntB*1 Taking cntA*cntB common in above equation we get: ans = cntA*cntB*[(k-1)+(k-2)+(k-3)+..+1] where [(k-1)+(k-2)+(k-3)+..+1] is the sum of first (k-1) natural numbers which is given by [k(k-1)/2], so the answer become. ans=cntA*cntB*[k(k-1)/2] and then we add the case 1 so the final answer would be: ans= (k*x)+(cntA*cntB*[k(k-1)/2]) If you are still in doubt then put in comments. answered 25 Apr '17, 00:19 1★arpit728 683●17●65 accept rate: 10%
 0 #include int main() { long long int t,i,j,k,sum,x; scanf("%lld",&t); while(t--) { long long int a,b,y; scanf("%lld%lld",&a,&b); char ch[a+1]; long long int ab[a]; scanf("%s",ch); x=0; for(i=0;i0) y=b*sum+x*ab[0]*k; else y=sum; printf("%lld\n",y); } return 0; }  plss help me w answered 24 Apr '17, 00:57 3★akshaycs 1●1 accept rate: 0% 2.5k●53●137●170
 0 #include int main(void){ int t ; scanf("%d",&t); for(int i =0; i unsigned long long int n,k; scanf("%d%d",&n,&k); char s[n+1]; scanf("%s",s); int j=0,a= 0,b =0, sum = 0; while(s[j] != NULL){ if(s[j] == 'a'){ a++; } else if(s[j] == 'b'){ sum = sum + a; b++; } j++; } unsigned long long int fin; fin = k*(k-1)/2*a*b+ k*sum; printf("%llu\n",fin); } return 0; }  same solution as of editorial but showing wrong answer. answered 24 Apr '17, 01:37 76●5 accept rate: 0% Fixed formatting...again. (24 Apr '17, 01:46) There is a big blunder in your code. Its HERE- scanf("%d%d",&n,&k); n and k aren't int, they are usigned long long int. Due to wrong string/format specifier (i.e. "%d") they, n and k were being assigned garbage values. (24 Apr '17, 01:50) But still it is showing wrong answer. (24 Apr '17, 01:56) Give me time to debug. (24 Apr '17, 02:04) correct answer is 5 for this test case not 3. (24 Apr '17, 02:18) 1 2 'ab' pairs for first 'b' and 3 'ab' pairs for second 'b'. You can verify by trying it in setter's solution. (24 Apr '17, 02:31) Yes, i got that. My bad. This is what happens when compres keep you sleep deprived haha XD (24 Apr '17, 02:36) Got AC for your code. You are suffering from overflow. Changed- int j=0,a= 0,b =0, sum = 0; to long long int j=0,a= 0,b =0, sum = 0; Reason for error- Overflow caused program to behave unpredictable. and gave error when judge ran it. (24 Apr '17, 03:14) Thanks a lot bro.. (24 Apr '17, 03:57) showing 5 of 9 show all
 0 A simple approach to the problem. Here's my code. int main() { int t; cin>>t; while(t--) { ll n, k; cin>>n>>k; string s; cin>>s; int i; vector v(n,0); for(i=n-1; i>=0; i++) { if(s[i]=='b') v[i]=1; if(i
 0 Why my solution is not working here is my approach: what I did is I calculated the no. of occurrences of sub-sequence "ab" in s and say it x. Then ans will be ans=x(k(k+1)/2). answered 24 Apr '17, 12:04 1★arpit728 683●17●65 accept rate: 10%
 0 @arpit728 How will you deal with case of- "baa" repeated twice == "baabaa" Your x is 0, so your ans reduces to 0, but there are occurances of ab in the final form. The concept of trailing 'a's has actually given a headache to many. As a hint I will say that there is a A.P. perspective possible to the problem. The number of "ab" formed by a particular a in FINAL string is an AP with common difference = No. of b in original string. Summing for all a, we get the answer.:) answered 24 Apr '17, 12:51 15.4k●1●20●66 accept rate: 18% @vijju123 got your point. (24 Apr '17, 14:15) arpit7281★

# Program

t=int(input()) while t>0: count=0 t=t-1 n,k=input().split() n,k=int(n),int(k) a=list(input()) a=a*k for i in range(len(a)): if a[i]=='a': for j in range(i,len(a)): if a[j]=='b': count=count+1 print(count)

2★ezio27
316
accept rate: 0%

 0 int main()  { int t; cin >> t; while(t--) {  unsigned ll n,k,b_count=0,ab_count=0; cin >> n >> k; string a,b; cin >> a; b=a; ll i; for(i=1;i<=k-1;i++) { a += b; } //cout << a; for(i=0;i
 0 Can anyone please explain to me why (k-1)/2 has been multiplied? would not only (K * cnta * cntb) be enough? answered 24 Apr '17, 16:17 2★pro1992 1 accept rate: 0% It is coming from the fact that there are nC2 ways of choosing a 'a' and a 'b' to form 'ab' by that method. And nC2 is nothing but n(n-1)/2. (24 Apr '17, 21:42)
 toggle preview community wiki:
Preview

By Email:

Markdown Basics

• *italic* or _italic_
• **bold** or __bold__
• image?![alt text](/path/img.jpg "title")
• numbered list: 1. Foo 2. Bar
• to add a line break simply add two spaces to where you would like the new line to be.
• basic HTML tags are also supported
• mathemetical formulas in Latex between \$ symbol

Question tags:

×15,680
×1,173
×891
×83
×8

question asked: 23 Apr '17, 20:17

question was seen: 1,986 times

last updated: 25 Apr '17, 00:45