题目来源:Problem - D - Codeforceshttps://codeforces.com/contest/1582/problem/D
官方思路:
解释:
对于数组元素个数进行 奇偶分析
当n为偶数时,我们将元素分成2/n对来处理,对于第一对 a1,a2;我们想让a1b1+a2b2为0,因此我们可以让b1=a2;b2=-a1;以此类推bi=ai+1;bi+1=-ai;
这样能保证
注意到 sum|bi|=sum|ai|<=maxN*maxA=;
因此不会数值越界;
当n为奇数时,
我们先将末位3个元素与其他元素分开处理,这样就可以按照n为偶数时的处理方法先处理好前n-3个元素。对于an-2,an-1,an。根据迪利克雷原理(抽屉原理),三个数中一定有两个同正或同负的数之和不等于0(两个抽屉分别代表正数和负数,当有三个元素时,那一定有一个抽屉里有两个元素)。这样我们假设这三个数中的两个同号的数分别记为ai和aj,第三个数为ak,这样再令
bi=-ak;
bj=-ak;
bk=ai+aj;
于是有the sum of ai⋅bi+aj⋅bj+ak⋅bk=0;
再进行越界判断:
对于前n-3个元素,|b1|+|b2|+|b3|...+|bn-3|<=maxa*(maxn-1-3)
所以最后3个元素
bn−2+bn−1+bnbn−2+bn−1+bn <= MAXA+MAXA+2⋅MAXA=4⋅MAXAMAXA+MAXA+2⋅MAXA=4⋅MAXA, \
总和不会超过maxa*maxn=
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define pb push_back;
#define end '\n';
void oper(vector<int>a, vector<int>b,int num)
{
for (int i = 0; i < num; i+=2)
{
b[i] = -a[i + 1];
b[i + 1] = a[i];
}
for (int i = 0;i < num; i ++)
{
cout << b[i] << ' ';
}
}
void solve()
{
int n;
cin >> n;
vector<int>a(n);
vector<int>b(n);
for(auto &x:a)
{
cin >> x;
}
if (n & 1)
{
oper(a, b, n - 3);
int i, j, k;//抽屉原理,三种组合必有一个同正或同负
if (a[n - 3] + a[n - 2])
{
k = a[n - 1];
j = a[n - 2];
i = a[n - 3];
cout << -k << ' ' << -k << ' ' << i+j << end;
}//在这里的区分上花了很多时间,希望能找到统一的规律
else if (a[n - 3] + a[n - 1])
{
k = a[n - 2];
j = a[n - 1];
i = a[n - 3];
cout << -k << ' ' << i + j << ' ' << -k << end;
}
else
{
k = a[n - 3];
j = a[n - 2];
i = a[n - 1];
cout << i + j << ' ' << -k << ' ' << -k << end;
}
}
else
{
oper(a, b, n);
cout << end;
}
}
int main()
{
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int t;
cin >> t;
for (int TwT = 1; TwT <= t; ++TwT)
{
solve();
}
}