题目背景
没有背景
我写不出来了qwq
题目描述
Chino给定了 n n n个数 a 1 . . . a n a_1...a_n a1...an,给定常数 s , m s,m s,m,她会轮流对这 n n n个数做 k k k组操作,每组操作包含以下几步:
1. s w a p ( a s , a m ) 1.swap(a_s,a_m) 1.swap(as,am)(交换 a s a_s as , a m a_m am)
2. 2. 2.将 n n n个数都向前平移一位(第 1 1 1个移动到第 n n n个位置上)
Chino想知道, k k k组操作后,这 n n n个数分别是多少?
Orz yky,dyh,wjk,jjy,cxr,gsy,cpy,zcy,tyz,yy,hz,zhr,ygg
输入格式
第一行,四个数, n , s , m , k n,s,m,k n,s,m,k
接下来一行 n n n个数,分别代表 a 1 , a 2 . . . a n a_1,a_2...a_n a1,a2...an
输出格式
输出一行, n n n个数,分别代表 a 1 , a 2 . . . a n a_1,a_2...a_n a1,a2...an
输入输出样例
输入 #1
4 1 2 3
1 2 3 4
输出 #1
1 2 3 4
说明/提示
对于
40
%
40\%
40%的数据,
1
≤
k
≤
1
0
7
1 \leq k \leq 10^7
1≤k≤107
对于
100
%
100\%
100%的数据,
1
≤
n
≤
80
1 \leq n \leq 80
1≤n≤80,
1
≤
s
<
m
≤
n
1 \leq s < m\leq n
1≤s<m≤n,
1
≤
k
≤
1
0
18
1 \leq k \leq 10^{18}
1≤k≤1018
所有数字均在
l
o
n
g
l
o
n
g
long long
longlong以内
解题思路
A
=
[
1
2
3
4
]
A = \begin{bmatrix} 1& 2 & 3 & 4 \end{bmatrix}
A=[1234]
考虑构造一个操作矩阵
在把数字进行操作时,只进行向前的操作
f[i][check(i - 1)] = 1//如果x > 0,check(x) = x; 如果x = 0,check(x) = n
B
=
[
0
0
0
1
1
0
0
0
0
1
0
0
0
0
1
0
]
B = \begin{bmatrix} 0& 0 & 0 & 1\\ 1& 0 & 0 & 0\\ 0& 1 & 0 & 0\\ 0& 0 & 1 & 0 \end{bmatrix}
B=⎣⎢⎢⎡0100001000011000⎦⎥⎥⎤
那么再把特殊情况s和m处理一下
x = i;
if (x == s) x = m;
if (x == m) x = s;
f[x][check(i - 1)] = 1;
B = [ 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 ] B =\begin{bmatrix} 1& 0 & 0 & 0\\ 0& 0 & 0 & 1\\ 0& 1 & 0 & 0\\ 0& 0 & 1 & 0 \end{bmatrix} B=⎣⎢⎢⎡1000001000010100⎦⎥⎥⎤
那么问题转换为了 A ∗ B k A *B^k A∗Bk
Code
#include <iostream>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
struct DT{
int n, m;
ll aed[100][100];
}A, B, M;
int n, k, l, x;
ll m;
int check (int x){
if (x == 0)
return n;
else return x;
}
DT operator *(DT a, DT b){//矩阵乘法
DT c;
memset (c.aed, 0, sizeof (c.aed));
c.n = a.n, c.m = b.m;
for (int k = 1; k <= a.m; k++)
for (int i = 1; i <= a.n; i++)
for (int j =1; j <= b.m; j++)
c.aed[i][j] += a.aed[i][k] * b.aed[k][j];
return c;
}
void power (ll m){//快速幂
if (m == 1)
{
M = B;
return;
}
power (m / 2);
M = M * M;
if (m % 2)
M = M * B;
}
int main(){
scanf ("%d%d%d%lld", &n, &k, &l, &m);
A.n = 1, A.m = n, B.n = n, B.m = n;
for (int i = 1; i <= n; i++)
scanf ("%lld", &A.aed[1][i]);
for (int i = 1; i <= n; i++)//构造操作矩阵
{
x = i;
if (i == k) x = l;
if (i == l) x = k;
B.aed[x][check (i - 1)] = 1;
}
/*for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
printf ("%lld ", B.aed[i][j]);
printf ("\n");
}*/
power (m);
A = A * M;
for (int i = 1; i <= n; i++)
printf ("%lld ", A.aed[1][i]);
}