C Strange Sorting

C. Strange Sorting
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

How many specific orders do you know? Ascending order, descending order, order of ascending length, order of ascending polar angle... Let's have a look at another specific order: d-sorting. This sorting is applied to the strings of length at least d, where d is some positive integer. The characters of the string are sorted in following manner: first come all the 0-th characters of the initial string, then the 1-st ones, then the 2-nd ones and so on, in the end go all the (d - 1)-th characters of the initial string. By the i-th characters we mean all the character whose positions are exactly i modulo d. If two characters stand on the positions with the same remainder of integer division byd, their relative order after the sorting shouldn't be changed. The string is zero-indexed. For example, for string 'qwerty':

Its 1-sorting is the string 'qwerty' (all characters stand on 0 positions),

Its 2-sorting is the string 'qetwry' (characters 'q', 'e' and 't' stand on 0 positions and characters 'w', 'r' and 'y' are on 1 positions),

Its 3-sorting is the string 'qrwtey' (characters 'q' and 'r' stand on 0 positions, characters 'w' and 't' stand on 1 positions and characters 'e' and 'y' stand on 2 positions),

Its 4-sorting is the string 'qtwyer',

Its 5-sorting is the string 'qywert'.

You are given string S of length n and m shuffling operations of this string. Each shuffling operation accepts two integer arguments k andd and transforms string S as follows. For each i from 0 to n - k in the increasing order we apply the operation of d-sorting to the substringS[i..i + k - 1]. Here S[a..b] represents a substring that consists of characters on positions from a to b inclusive.

After each shuffling operation you need to print string S.

Input

The first line of the input contains a non-empty string S of length n, consisting of lowercase and uppercase English letters and digits from 0 to 9.

The second line of the input contains integer m – the number of shuffling operations (1 ≤ m·n ≤ 106).

Following m lines contain the descriptions of the operations consisting of two integers k and d (1 ≤ d ≤ k ≤ n).

Output

After each operation print the current state of string S.

Sample test(s)
input
qwerty
3
4 2
6 3
5 2
output
qertwy
qtewry
qetyrw
Note

Here is detailed explanation of the sample. The first modification is executed with arguments k = 4, d = 2. That means that you need to apply 2-sorting for each substring of length 4 one by one moving from the left to the right. The string will transform in the following manner:

qwerty  →  qewrty  →  qerwty  →  qertwy

Thus, string S equals 'qertwy' at the end of first query.

The second modification is executed with arguments k = 6, d = 3. As a result of this operation the whole string S is replaced by its 3-sorting:

qertwy  →  qtewry

The third modification is executed with arguments k = 5, d = 2.

qtewry  →  qertwy  →  qetyrw

因为我们知道 每次进来一个点 就有一个点 出去 , 这里面可能存在 有些点一直在这个区间中,然后我们可以知道最后进来的那个点出了步数不够,其他情况下一定能够出来,那么我们从这个最后一个点出发模拟出他的最后出去的路径,然后可以发现不再这个路径上的点一定是循环再这个区间内, 因为 每次进来的 一个数必将会出去,那么出去又是在这条路径上,于是他们就一定不能出去了,这样把他们的循环节路径一一记下来,那么就下来的工作就剩下枚举每个点 然后求出他们的最后输出在哪里就可以了,因为对于k-1及以后点点 可以通过当前位置和剩下位置,在路径上找出最后的 位置

在循环节内的点 也可以根据循环节路径计算出最后一次会在那个位置出现

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
using namespace std;
char str[2][1000005];
int k,d,n,len,tim;
int R[1000005],ge;
int RFE[1000005],RE[1000005];
vector<int> F[10000005];
void solve(int st, int loc){
     int G=k/d;
     int H=k%d;
     while(loc!=0){
        RFE[loc]=1;
        int rr=loc%d;
        int num=rr*G;
        if(H!=0){
            if( H<rr) num+=H;
            else num+=rr;
        }
          num+=loc/d;
          loc=num-1;
          R[ge]=loc;
          RE[loc]=ge++;
     }
}
void xunhun(int nu, int loc){
     F[nu].clear();
     int G=k/d;
     int H=k%d;
     int rw=0;
     while(RFE[loc]==0){
          F[nu].push_back(loc);
          RFE[loc]=nu;
          RE[loc]=rw++;
          int rr=loc%d;
          int num=rr*G;
          if(H!=0){
            if( H<rr ) num+=H;
            else num+=rr;
          }
          num+=loc/d;
          loc=num-1;
     }
}
void inti(int k){
     for(int i=0; i<=k; ++i) RFE[i]=0;
}
int main()
{
    while(scanf("%s",str[0])==1){
          len = strlen(str[0]);
          scanf("%d",&n);
          int now=0;
          for(int i=0; i<n; ++i){
                now=1-now;
             scanf("%d%d",&k,&d);
              inti(k);
              ge=0;
              tim=len-k+1;
              str[now][0]=str[1-now][0];
              solve(0,k-1);
              for(int j=k-1; j<len; ++j){
                        int loc;
                if( len-j >= ge ) loc=R[ge-1]+j-k+1+ge;
                else loc = R[len-j-1]+j-k+1+len-j;
                  str[now][loc]=str[1-now][j];
              }
              int nu=2;
              for(int j=1; j<k-1; ++j)if(RFE[j]==0){
                 xunhun(nu,j); nu++;
              }
              for(int j=1; j<k-1; ++j)
                if(RFE[j]==1){
                  if(tim>=ge-RE[j]) str[now][ ge-RE[j]-1 ]=str[1-now][j];
                   else str[now][R[RE[j]+tim]+tim]=str[1-now][j];

              }else{
                  int sz=F[RFE[j]].size();
                  int ddd = F[ RFE[j] ][ (RE[j]+tim%sz)%sz   ];
                  int loc = tim+ddd;
                  str[now][loc]=str[1-now][j];
              }
              str[now][len]=0;
              printf("%s\n",str[now]);
          }
    }

    return 0;
}
View Code

 

 

posted @ 2014-11-10 20:16  来自大山深处的菜鸟  阅读(267)  评论(0编辑  收藏  举报