题目描述
现在给你一个长度为n 的a 序列,同时给你一个整数k,接下来我们要做k次操作。每次操作如下:
- 找出当前a 序列的最大值,设为d。
- 对于a 序列里面的每个数,我们把a[i] 替代为d − a[i]。
你的目标是求出k 次这样的操作以后的最终的序列。
输入
输入的第一行是一个正整数t(t ≤ 100),表示数据的组数。
接下来每组数据,先输入两个正整数n 和k(1 ≤ n ≤ 2 × 10^5, 1 ≤ k ≤ 10^18),然后接下来是n 个整数a[i](−10^9 ≤ a[i] ≤ 10^9)。
输入数据保证所有n 的总和不超过2 × 10^5。
输出
对于每组数据,输出k 次操作以后的结果,每组数据一行。
样例输入
3
2 1
-199 192
5 19
5 -1 4 2 0
1 2
69
样例输出
391 0
0 6 1 3 5
0
数据范围限制
题目解法
首先看到这道题的数据,200000。暴力是肯定不行的,所以我们考虑优化。
模拟一下第一个样例的第二组数据(因为代表性比较强:
5 -1 4 2 0
第一次操作:
0 6 1 3 5
第二次操作:
6 0 5 3 1
第三次操作:
0 6 1 3 5
我们可以看到,这题还是有优化方法的。那就是周期。
以每两组为一个周期,最后K%2找到最终答案。
#include<cstdio>
using namespace std;
long long t,n,k,a[5000005],ans,ans2;
long long max(long long x,long long y)
{
if(x>y) return x;
else return y;
}
int main()
{
freopen("operate.in","r",stdin);
freopen("operate.out","w",stdout);
scanf("%lld",&t);
while(t)
{
t--,scanf("%lld%lld",&n,&k);
ans=-1000000000,ans2=-1000000000;
for(long long i=1;i<=n;++i) scanf("%lld",&a[i]),ans=max(ans,a[i]);
for(long long i=1;i<=n;++i) a[i]=ans-a[i],ans2=max(ans2,a[i]);
k=(k-1)%2;
if(k>0) for(long long i=1;i<=n;++i) a[i]=ans2-a[i];
for(long long i=1;i<=n;++i) printf("%lld ",a[i]);
printf("\n");
}
return 0;
}