# Suffix Rotation

### Problem Statement :

```Megan is playing a string game with the following rules:

It starts with a string, s.
During each turn, she performs the following move:

Choose an index in s. The chosen index must be strictly greater than any index chosen in a prior move.
Perform one or more circular rotations (in either direction) of the suffix starting at the chosen index.
For example, let's say s = abcdefjghi. During our move, we choose to do three right rotations of the suffix starting at index 6:
image
Note that this counts as one move.

The goal of the game is to convert s into the lexicographically smallest possible string in as few moves as possible. In other words, we want the characters to be in alphabetical order.
Megan plays this game g times, starting with a new string s each time. For each game, find the minimum number of moves necessary to convert s into the lexicographically smallest string and print that number on a new line.

Input Format

The first line contains an integer, g, denoting the number of games.
Each of the g subsequent lines contains a single string denoting the initial value of string s for a game.

Constraints
1 <= g <= 100
1 <= |s| <= 1000

s consists of lowercase English alphabetic letters only.
Output Format

For each game, print an integer on a new line denoting the minimum number of moves required to convert s into the lexicographically smallest string possible.```

### Solution :

```                            ```Solution in C :

In C++ :

#include <bits/stdc++.h>
using namespace std;

#define N 1010
#define inf 1010

int t;
char s[N];
map <string, int> mp;

int solve(char *s) {
//	puts(s);
int len = strlen(s);
if (!len) return 0;
if (mp.count(s)) return mp[s];
char c = *min_element(s, s + len);
if (s[0] == c) return mp[s] = solve(s + 1);
int rlt = 0;
char ss[N];
int runs = 0;
bool vis[N];
for (int i = 0; i < len; i ++) if (s[i] != c) {
ss[runs] = s[i];
int prv = i ? i - 1 : len - 1;
vis[runs++] = s[prv] == c;
if (i < len - 1 && s[i+1] == c) rlt ++;
}
ss[runs] = 0;
len = runs;
c = *min_element(ss, ss + len);
bool start_c = 0;
for (int i = 0; i < len; i ++) {
if (vis[i] && ss[i] == c) {
start_c = 1; break;
}
}
int mn = inf;
char sss[N];
for (int i = 0; i < len; i ++) if (vis[i]) {
if (start_c && ss[i] != c) continue;
for (int j = 0; j < len; j ++) sss[j] = ss[(j+i)%len];
sss[len] = 0;
mn = min(mn, solve(sss));
}
return mp[s] = rlt + mn;
}

int main() {
//	freopen("s.in", "r", stdin);
//	freopen("s.out", "w", stdout);
scanf("%d", &t);
while (t --) {
scanf("%s", s);
printf("%d\n", solve(s));
}
return 0;
}

In Java :

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {
static class SH {
int id=0;
int[] cnt;
String cs;
SH(String s,int[] ant) {
cs=s;
cnt=Arrays.copyOf(ant,26);
prep();
}
void prep() {
StringBuilder sb=new StringBuilder();
while(id<cs.length()) {
char mc=getMC();
if(mc==cs.charAt(id)) {
++id;
--cnt[mc-'a'];
}
else break;
}
/*
for(int i=id;i<chs.length;++i) {
if(i!=id&&chs[i]==chs[i-1]) {
--cnt[chs[i]-'a'];
} else {
sb.append(chs[i]);
}
}
cs=sb.toString();
*/
cs=cs.substring(id);
id=0;
}
public int mm(){
if(hm.containsKey(cs)) return hm.get(cs);
if(0==cs.length()) return 0;
char mc=getMC();
String[] stx=cs.split(""+mc);
int res=0;
cnt[mc-'a']=0;
StringBuilder sb=new StringBuilder();
for(String x:stx) {
if(x.length()!=0) {
sb.append(x);
++res;
}
}
if(cs.charAt(cs.length()-1)!=mc) --res;
mc=getMC();
String ns="";
int mt=sb.length();
int j=0;
HashSet<String> hs=new HashSet();
for(String bx:stx) {
if(j==res) break;
if(bx.length()==0) continue;
sb.delete(0,bx.length());
sb.append(bx);
String ts=sb.toString();
int tmt=cMC(ts,mc);
if(tmt<mt) {
ns=ts;
mt=tmt;
hs.clear();
} else if(tmt==mt) {
}
++j;
}
int rm=Integer.MAX_VALUE;
for(String bx:hs) {
int nm=new SH(bx,cnt).mm();
if(nm<rm) rm=nm;
}
res+=rm;
hm.put(cs,res);
return res;
}
int cMC(String st,char x) {
int res=0;
String[] nxt=st.split(""+x);
for(String tt:nxt) {
if(tt.length()!=0) ++res;
}
if(st.charAt(st.length()-1)!=x) --res;
if(st.charAt(0)==x) --res;
return res;

}
char getMC() {
for(char x='a';x<='z';++x) {
if(cnt[x-'a']!=0) return x;
}
return '*';
}
}
static HashMap<String,Integer> hm=new HashMap();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int q = in.nextInt();
for(int a0 = 0; a0 < q; a0++){
String s = in.next();
int[] cnt=new int[26];
for(char x:s.toCharArray()) ++cnt[x-'a'];
SH t=new SH(s,cnt);
System.out.println(t.mm());
}
}
}

In C :

#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#define FOR(a,b,c) for(int a=(b),_for=(c);a<_for;++a)
#define M 1000
#define Z 26
char c[M+5];
int n, P[M+5], A[M+5], B[M+5], C[Z+5], D[M+5], E[M+5];
int min(int a, int b)
{
return a < b ? a : b;
}

int n;
int p[M+5];
char c[M+5];
int cnt[Z+5];
int dp[M+5];
int nju[M+5];
int nx[M+5];
int isti[M+5];

void solve(){
scanf ("%s",c);
n=strlen(c);
FOR(i,0,n) p[i]=Z-1-(c[i]-'a');
FOR(i,0,Z) cnt[i]=0;
FOR(i,0,n) cnt[p[i]]++;
FOR(i,0,n) dp[i]=0;
FOR(i,0,n) nju[i]=0;
FOR(i,0,n) nx[i]=0;
FOR(i,0,n) isti[i]=0;
FOR(cl,0,Z){
if (!cnt[cl]) continue;
FOR(i,0,n) dp[i]=nju[i];
memset(nju,-1,n*sizeof(int));
memset(isti,0,n*sizeof(int));
int last=-1,prvi=-1,sum=0,b1=n,b2=n;
FOR(i,0,n) if (p[i]<=cl){
if (last>=0){
nx[last]=i;
if (p[last]!=p[i] && p[i]==cl) isti[i]=1,sum++;
}
else prvi=i;
last=i;
}
nx[last]=prvi;
//        FOR(i,0,n) printf ("%d -> %d\n",i,nx[i]);
if (p[last]!=p[prvi] && p[prvi]==cl) isti[prvi]=1,sum++;
int pb1=-1;
FOR(i,0,n) if (p[i]==cl && p[nx[i]]!=cl){
b2=min(b2,dp[nx[i]]);
//            printf ("%d -> %d\n",i,b2);
if (b2<b1)
{
int temp = b1;
b1 = b2;
b2 = temp;
pb1=i;
}
}
//        printf ("%d %d %d ???\n",sum,b1,pb1);
sum+=b1-1;
if (pb1==-1) sum=-1;
bool flag=0;
FOR(i,0,n){
if (p[i]>cl) continue;
if (p[i]<cl || !isti[i]){
nju[i]=sum+1;
continue;
}
if (b1==b2 || b2==n){
nju[i]=sum;
continue;
}
nju[i]=sum;
flag=1;
}
if (flag){
for (int i=pb1;i>=0 && flag;--i){
if (isti[i]) nju[i]++,flag=0;
}
for (int i=n-1;i>=0 && flag;--i){
if (isti[i]) nju[i]++,flag=0;
}
}
//        FOR(i,0,n) printf ("%d %d %d\n",i,isti[i],nju[i]);
//        printf ("\n");
}
printf ("%d\n",nju[0]);

}

int main(){
int znj;
scanf ("%d",&znj);
while(znj--) solve();
return 0;
}

In Python3 :

#!/bin/python3

import sys

def bestlastrotation(s,groups,letters,memos):
if len(letters) < 3:
return groups[0]
mn = letters[0]
mn2 = letters[1]
mn3 = letters[2]
lens = len(s)

groups2 = []
for g in groups:
i = g
while s[i] == mn:
i = (i + 1) % lens
if s[i] == mn2 and s[g-1] != mn2:
groups2.append([g,i])

if len(groups2) == 0: return groups[0]
if len(groups2) == 1: return groups2[0][0]

for gg in groups2:
j = gg[1]
while s[j] == mn2 or s[j] == mn:
j = (j + 1) % lens
if s[j] != mn3:
return gg[0]
else:
gg.append(j)

if len(letters) < 4:
return groups2[0][0]

groupset = set(x[0] for x in groups2)

ans = 0
best = lens
for g in groupset:
s2 = (s[g:]+s[:g]).replace(mn,'')
result = min_rotations(s2,memos)
if best > result:
best = result
ans = g

return ans

def min_rotations(s,memos):
if s in memos:
return memos[s]

letters = sorted(set(s))
mn = min(letters)
ans = 0

while mn != max(letters):

i = 0
while s[i] == mn:
i += 1
if i > 0:
s = s[i:]

groups = []
for i in range(len(s)):
if s[i] == mn and s[i-1] != mn:
groups.append(i)

ans += len(groups)

if len(groups) == 1:
g = groups[0]
s = s[g:] + s[:g]

if len(groups) > 1:
g = bestlastrotation(s,groups,letters,memos)
s = s[g:] + s[:g]

s = s.replace(mn,'')
letters = letters[1:]
mn = min(letters)

memos[s] = ans
return ans

q = int(input().strip())
for a0 in range(q):
s = input().strip()
print(min_rotations(s,dict()))```
```

## Square-Ten Tree

The square-ten tree decomposition of an array is defined as follows: The lowest () level of the square-ten tree consists of single array elements in their natural order. The level (starting from ) of the square-ten tree consists of subsequent array subsegments of length in their natural order. Thus, the level contains subsegments of length , the level contains subsegments of length , the

## Balanced Forest

Greg has a tree of nodes containing integer data. He wants to insert a node with some non-zero integer value somewhere into the tree. His goal is to be able to cut two edges and have the values of each of the three new trees sum to the same amount. This is called a balanced forest. Being frugal, the data value he inserts should be minimal. Determine the minimal amount that a new node can have to a

## Jenny's Subtrees

Jenny loves experimenting with trees. Her favorite tree has n nodes connected by n - 1 edges, and each edge is ` unit in length. She wants to cut a subtree (i.e., a connected part of the original tree) of radius r from this tree by performing the following two steps: 1. Choose a node, x , from the tree. 2. Cut a subtree consisting of all nodes which are not further than r units from node x .

## Tree Coordinates

We consider metric space to be a pair, , where is a set and such that the following conditions hold: where is the distance between points and . Let's define the product of two metric spaces, , to be such that: , where , . So, it follows logically that is also a metric space. We then define squared metric space, , to be the product of a metric space multiplied with itself: . For

## Array Pairs

Consider an array of n integers, A = [ a1, a2, . . . . an] . Find and print the total number of (i , j) pairs such that ai * aj <= max(ai, ai+1, . . . aj) where i < j. Input Format The first line contains an integer, n , denoting the number of elements in the array. The second line consists of n space-separated integers describing the respective values of a1, a2 , . . . an .

## Self Balancing Tree

An AVL tree (Georgy Adelson-Velsky and Landis' tree, named after the inventors) is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. We define balance factor for each node as : balanceFactor = height(left subtree) - height(righ