发现每一次的灵能传输都是对前缀和s[i - 1]和s[i]的一次交换
我们发现只剩下s1没有相减,在这里我们可以添加一个为0的s0,使整个式子表示完整
故为求max(s[i], s[i - 1])的最小值(发现当s单调时可以成立)
由于s[0]和s[n]的位置不变,但是s[0]和s[n]不一定是最大值或者最小值
故可以进行一个贪心策略
- #include
- using namespace std;
- typedef long long ll;
- const int N = 3e5 + 10;
- ll n, s0, sn, a[N], s[N], ans[N];
- bool st[N];
- void solve()
- {
- memset(st, 0, sizeof st);
- cin >> n;
- s[0] = 0;
- for(int i = 1; i <= n; i ++)cin >> a[i];
- for(int i = 1; i <= n; i ++)s[i] = s[i - 1] + a[i];
- s0 = s[0];
- sn = s[n];
- if(s0 > sn)swap(s0, sn);
- sort(s, s + n + 1);//注意此处两边的数的范围
- for(int i = 0; i <= n; i ++)
- {
- if(s[i] == s0)
- {
- s0 = i;
- break;
- }
- }
- for(int i = n; i >= 0; i --)
- {
- if(s[i] == sn)
- {
- sn = i;
- break;
- }
- }
- ll l = 0, r = n;
- for(int i = s0; i >= 0; i -= 2)
- {
- st[i] = true;
- ans[l ++] = s[i];
- }
- for(int i = sn; i <= n; i += 2)
- {
- st[i] = true;
- ans[r --] = s[i];
- }
- for(int i = 0; i <= n; i ++)
- {
- if(!st[i])
- {
- ans[l ++] = s[i];
- }
- }
- ll res = 0;
- for(int i = 1; i <= n; i ++)
- {
- res = max(res, abs(ans[i] - ans[i - 1]));// s[i] - s[i - 1] = a[i]
- }
- cout << res << '\n';
- }
- int main()
- {
- ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
- int t;
- cin >> t;
- while(t --)
- {
- solve();
- }
- return 0;
- }