一、最小表示法:
   给定一个字符串S(1----N),如果我们不断把它的最后一个字符放到开头,最终会得到n个字符串,称这n个字符串是循环同构的。这些字符串中字典序最小的一个,称为字符串S的最小表示。

   最小表示法求解:
   (1)我们先把S复制一份接到它的结尾,得到的字符串记为SS。
   (2)初始化 i = 1,j = 2。
   (3)通过直接向后扫描的方法,比较b(i)与b(j)两个循环同构串。
      如果扫描了n个字符后仍然相等,说明S只由1种字符构成,任意b(i)都是它的最小表示。
      如果在 i+k 与 j+k 处发现不相等:
      (1)若SS(i+k)>SS(j+k) 令 i=i+k+1。若此时 i=j ,再令 i = i + 1。
      (2)若SS(i+k)<SS(j+k) 令j=j+k+1。若此时 j=i,再令 j = j +1。

   (4)若i>n,b(j)为最小表示,若j>n,b(i)为最小表示;否则重复第三步。

时间复杂度为O(n)。

int n=strlen(s+1);
for(int i=1;i<=n;i++)
{
    s[n+i]=s[i];
}

int i=1,j=2,k;

while(i<=n&&j<=n)
{
    for(k=0;k<n&&s[i+k]==s[j+k];k++)
        continue;

    if(k==n) break;//S只由一个字符构成

    if(s[i+k]>s[j+k])
    {
        i=i+k+1;
        if(i==j) i++;
    }
    else
    {
        j=j+k+1;
        if(i==j) j++;
    }
}
ans=min(i,j); //b[ans]是最小表示。