Alice和Bob发明了一个新的旋转游戏。首先,Bob给定 N N N个数组成的序列,并把该序列平均分配成若干个块,每块正好包含 K K K个数( K K K能整除 N N N)。第一块由第 1 1 1到第 K K K个数构成,第二块由第 K + 1 K+1 K+1个数到第 2 K 2K 2K个数构成,以此类推。
接着,Bob要求Alice对这个序列进行一系列操作,操作有以下两种:
1.把每块里面的数向左或右旋转 X X X个位置;
2.把整个序列向左或向右旋转 X X X个位置。
注意操作2会改变每一块里面的数。
在执行完一系列操作后,Alice把最终的序列告诉了Bob。Bob的任务就是找到初始序列。
第一行输入三个正整数:序列的长度 N ( 1 ≤ N ≤ 100 , 000 ) N(1≤N≤100,000) N(1≤N≤100,000),每一块的大小 K ( 1 ≤ K ≤ 100 , 000 ) K(1≤K≤100,000) K(1≤K≤100,000),操作次数 Q ( 1 ≤ Q ≤ 100 , 000 ) Q(1≤Q≤100,000) Q(1≤Q≤100,000)。
接下来 Q Q Q行,每行包含两个整数:操作种类 A ( 1 ≤ A ≤ 2 ) A(1≤A≤2) A(1≤A≤2)和旋转位数 X ( − 100 , 000 ≤ X ≤ 100 , 000 ) X(-100,000≤X≤100,000) X(−100,000≤X≤100,000),其中负数表示向左旋转,整数表示向右旋转。
最后一行输入 N N N个数 Z i ( 0 ≤ Z i ≤ 100 , 000 ) Z_i(0≤Z_i≤100,000) Zi(0≤Zi≤100,000)表示最终序列。
一行输出初始序列。
输入1:
4 2 2
2 2
1 1
3 2 1 0
输入2:
8 4 4
1 3
1 15
1 -5
2 -1
6 10 14 19 2 16 17 1
输入3:
9 3 5
1 1
2 -8
2 9
1 1
2 -4
3 1 8 7 4 5 2 6 9
输出1:
0 1 2 3
输出2:
6 10 14 1 2 16 17 19
输出3:
5 3 6 9 7 1 8 2 4
40%的数据满足 N ≤ 100 N≤100 N≤100.
70%的数据满足 K ≤ 100 K≤100 K≤100.
#include
#include
using namespace std;
#define N 100010
struct
{
int x,y;
}a[N];
int b[N],c[N],d[N],ans[N];
int main()
{
int n,k,q,i,j,x,y;
scanf("%d%d%d",&n,&k,&q);
for(i=1;i<=q;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].y=-a[i].y;
if(a[i].x==1) a[i].y=(a[i].y%k+k)%k; else a[i].y=(a[i].y%n+n)%n;
}
for(i=1;i<=n;i++) scanf("%d",&b[i]);
int fi=1;
for(i=q;i;i--)
{
x=a[i].x,y=a[i].y;
fi=(fi+y-1)%k+1;
if(x==2)
{
int l=y/k,t=y%k;
if(t)
{
int h=(k-fi+1)%k+1;
if(h+t-1<=k)
{
c[h+t]--;
c[1]+=l;
c[h]++;
}
else
{
c[1]+=l+1;
c[(h+t)%k]--;
c[h]++;
}
}
else c[1]+=l;
}
}
d[0]=0;
for(i=1;i<=k;i++) d[i]=((d[i-1]+c[i])%(n/k)+n/k)%(n/k);
int l=fi;
for(i=1;i<=k;i++)
{
for(j=0;j<n/k;j++)
ans[((d[i]+j)%(n/k))*k+l]=b[i+j*k];
l=l%k+1;
}
for(i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}