C Strange Sorting
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.
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).
After each operation print the current state of string S.
qwerty
3
4 2
6 3
5 2
qertwy
qtewry
qetyrw
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及以后点点 可以通过当前位置和剩下位置,在路径上找出最后的 位置
在循环节内的点 也可以根据循环节路径计算出最后一次会在那个位置出现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
#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; }