题意翻译
给出一个长度为 n n n的序列 a a a以及一个 k k k,我们定义进行一次操作分以下两步:
设
d
d
d表示序列中的最大值
对于每个
i
∈
[
1
,
n
]
i\in[1,n]
i∈[1,n],将
a
i
a_i
ai替换成
d
−
a
i
d-a_i
d−ai。
现在请你输出进行
k
k
k次操作后的序列。
思路
- 表面上是一个区间维护最后查询,可数据 1 < k < = 1 0 18 1<k<=10^{18} 1<k<=1018 O ( k ) ∗ 多 组 数 据 O(k)* 多组数据 O(k)∗多组数据一定不行
- 那让我们思考
O
(
1
)
O(1)
O(1)做法:
先模拟一下样例:
3
2 1
-199 192
5 19
5 -1 4 2 0
1 2
69
第一组:
[ 192 − ( − 199 ) , 192 − 192 ] − > [ 391 , 0 ] [192-(-199),192-192]->[391,0] [192−(−199),192−192]−>[391,0]
第二组:
[
5
−
5
,
5
−
(
−
1
)
,
5
−
4
,
5
−
2
,
5
−
0
]
−
>
[
0
,
6
,
1
,
3
,
5
]
[5-5,5-(-1),5-4,5-2,5-0]->[0,6,1,3,5]
[5−5,5−(−1),5−4,5−2,5−0]−>[0,6,1,3,5]
[
6
−
0
,
6
−
6
,
6
−
1
,
6
−
3
,
6
−
5
]
−
>
[
6
,
0
,
5
,
3
,
1
]
[6-0,6-6,6-1,6-3,6-5]->[6,0,5,3,1]
[6−0,6−6,6−1,6−3,6−5]−>[6,0,5,3,1]
[
6
−
6
,
6
−
0
,
6
−
5
,
6
−
3
,
6
−
1
]
−
>
[
0
,
6
,
1
,
3
,
5
]
[6-6,6-0,6-5,6-3,6-1]->[0,6,1,3,5]
[6−6,6−0,6−5,6−3,6−1]−>[0,6,1,3,5]
[
6
−
0
,
6
−
6
,
6
−
1
,
6
−
3
,
6
−
5
]
−
>
[
6
,
0
,
5
,
3
,
1
]
[6-0,6-6,6-1,6-3,6-5]->[6,0,5,3,1]
[6−0,6−6,6−1,6−3,6−5]−>[6,0,5,3,1]
- 到这里我们可以看到1次变换之后 d d d已经固定了 M a x ( a ) − M i n ( a ) Max(a)-Min(a) Max(a)−Min(a),不懂的看下面:
1 [ a 1 , a 2 , a 3... , M a x , M i n ] [a1,a2,a3...,Max,Min] [a1,a2,a3...,Max,Min]//两数位置不定
2 [ M a x − a 1 , M a x − a 2...0 , M a x − M i n ] [Max-a1,Max-a2...0,Max-Min] [Max−a1,Max−a2...0,Max−Min]//x-y当x固定时,y越小值越大,所以Max-MIn就是最大的;
3 [ ( M a x − M i n ) − ( M a x − a 1 ) , ( M a x − M i n ) − ( M a x − a 2 ) . . . M a x − M i n , 0 ] [(Max-Min)-(Max-a1),(Max-Min)-(Max-a2)...Max-Min,0] [(Max−Min)−(Max−a1),(Max−Min)−(Max−a2)...Max−Min,0]
可以发现,原来的Max和Min现在一定都是一个是0,一个是最大值: M a x − M i n Max-Min Max−Min;
代码实现
- 输入后找到 M a x Max Max和 M i n Min Min;
- 如果 k m o d 2 = 1 k mod 2=1 kmod2=1输出 M a x − a i {Max-a_i} Max−ai
- 否则输出 a i − M i n {a_i-Min} ai−Min( M a x − M i n − ( M a x − a i ) = − M i n + a i = a i − M i n Max-Min-(Max-a_i)=-Min+a_i=a_i-Min Max−Min−(Max−ai)=−Min+ai=ai−Min)
#include<bits/stdc++.h>
using namespace std;
int min(int a,int b){return a>b?b:a;}
int max(int a,int b){return a>b?a:b;}
int a[200039],N,T;
long long k;
int Max,Min;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%lld",&N,&k);
Min=1000000000;Max=-1000000000;
for(int i=1;i<=N;i++){
scanf("%d",&a[i]);
Min=min(a[i],Min);
Max=max(a[i],Max);
}
if(k%2==1){
for(int i=1;i<=N;i++)printf("%d ",Max-a[i]);
}
else{
for(int i=1;i<=N;i++)printf("%d ",a[i]-Min);
}
printf("\n");
}
}