题目链接:Problem - D - Codeforces Vupsen, Pupsen and 0
给你一个长度为 1 e 5 1e5 1e5的序列a,a中所有的元素均不等于0,范围是 [ − 1 e 4 , 1 e 4 ] [-1e4,1e4] [−1e4,1e4],需要构造一个长度相等的B序列(不含0),满足 ∑ a i ∗ b i = 0 \sum a_i*b_i =0 ∑ai∗bi=0,而且这道题要求 ∑ ∣ b i ∣ < = 1 e 9 \sum |b_i|<=1e9 ∑∣bi∣<=1e9。这个约束对于a数组是成立的, ∑ ∣ a i ∣ < = 1 e 9 \sum |a_i|<=1e9 ∑∣ai∣<=1e9,所以这道题的构造和A数组脱不开关系。我们发现任意两个不等于0的数,x和y,总满足 x ∗ ( − y ) + y ∗ ( − x ) = 0 x*(-y)+y*(-x)=0 x∗(−y)+y∗(−x)=0,所以当n是偶数时直接输出即可。而当n是奇数的时候,我们可以只保留最后三个数,其他的都用上述方法构造。三个数构造我们可以转化为两个数构造。即 x ∗ ( y + z ) + ( − x ) ∗ y + ( − y ) ∗ z = 0 x*(y+z)+(-x)*y+(-y)*z=0 x∗(y+z)+(−x)∗y+(−y)∗z=0,但是我们需要判断其中两个数的和是否为0,如果为0,则b序列中含0,不合题意,一定存在一组解,因为三个数不可能互为相反数。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int T,n,a[N];
void print(int x,int y,int z){
if(x+y!=0){
printf("%d %d %d\n",-z,-z,x+y);
return;
}
if(x+z!=0){
printf("%d %d %d\n",-y,x+z,-y);
return;
}
if(y+z!=0){
printf("%d %d %d\n",y+z,-x,-x);
return;
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
if(n&1){
for(int i=1;i<n-2;i+=2){
printf("%d %d ",-a[i+1],a[i]);
}
int x=a[n-2],y=a[n-1],z=a[n];
print(x,y,z);
}
else{
for(int i=1;i<=n;i+=2){
if(i==n-1){
printf("%d %d\n",-a[i+1],a[i]);
}
else printf("%d %d ",-a[i+1],a[i]);
}
}
}
return 0;
}