题意:每经过一单位时间,右移一位。t单位时间循环右移 t 位。 (字符串循环右移, 其实不用这么麻烦。。)。t 可能超出 n范围 故取模
每个元素乘上一个 k^t 。这里因为数字非常大,故需要使用快速幂方法。 就是移位。。
WA了很多次。 需要注意的是:
1. 快速幂疏忽了几点。current 每次都需要乘方的。 而且myk = myk * current 而不是加
long long myk = 1;
long long current = k;
if(tt == 0)
myk = 0;
while(tt) {
if(tt & 1) {
myk = (myk *current) % MOD;
}
current = (current * current) % MOD;
tt >>= 1;
}
而不是
while(tt) {
if(tt & 1) {
myk = (myk +current) % MOD;
} else
current = (current * current) % MOD;
tt >>= 1;
}
2. 上面的myk 和current 每次都取模。 表面上其实取int就可以。。但是这样会出现错误。主要原因是, 如果两个相乘的数都是int, 那么如果其乘积(用int临时变量保存)超过了int, 就会照成溢出,使得结果不正确。 所以应该将其类型设置为long long 这样, 乘上一个int 后产生的结果保存的临时变量为 long long 保证结果的正确
3. reverse代码可用可不用。有点使得问题复杂化了。一下分别给出两个版本的代码。。
#include <iostream>
using namespace std;
const int N = 10010;
int a[N];
const int MOD = 1000000007;
void rever(int *a, int l, int r) {
while(l < r) {
swap(a[l++], a[r--]);
}
}
void myreverse(int* a, int n, int k) {
rever(a, n-k, n-1);
rever(a, 0, n-k-1);
rever(a, 0, n-1);
}
int main() {
int cass;
cin >> cass;
while(cass--) {
int n, t, k;
cin >> n >> t >> k;
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
if(t == 0) {
for(int i = 0; i < n-1; i++) {
printf("%d ", a[i]);
}
printf("%d\n", a[n-1]);
continue;
}
int tt = t;
long long myk = 1;
long long current = k;
if(tt == 0)
myk = 0;
while(tt) {
if(tt & 1) {
myk = (myk *current) % MOD;
}
current = (current * current) % MOD;
tt >>= 1;
}
//myk %= n;
int yi = t % n;
// 循环移位问题
if(yi != 0)
myreverse(a, n, yi); //这里也可以调用系统的reverse
for(int i = 0; i < n; i++) {
a[i] = (a[i] * myk) % MOD;
}
for(int i = 0; i < n-1; i++) {
printf("%d ", a[i]);
}
printf("%d\n", a[n-1]);
}
return 0;
}
#include <iostream>
using namespace std;
const int N = 10010;
int a[N];
const int MOD = 1e9 + 7;
long long pow(int k, int t) {
if(k == 0)
return 0;
if(k == 1)
return 1;
long long myk = 1;
long long current = k;
while(t) {
if(t & 1) {
myk = (myk *current) % MOD;
}
current = (current * current) % MOD;
t >>= 1;
}
return myk;
}
int main() {
int cass;
cin >> cass;
while(cass--) {
int n, t, k;
cin >> n >> t >> k;
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
long long myk = pow(k, t);
int yi = t % n;
for(int i = 0; i < n; i++) {
a[i] = (a[i] * myk) % MOD;
}
printf("%d", a[(n-yi)%n]);
for(int i = 1; i < n; i++) {
printf(" %d", a[(n+i-yi)%n]);
}
printf("\n");
}
return 0;
}