题目大意:
思路解析:
我们可以发现偶数情况下,我们可以无限做 k == n的操作,这样一定会让数组变为非降序数组。
但是奇数情况下,最后一个数没有办法发生变化,所以我们只能统计怎样在保证i--n为非降序情况下最多能在第i个位置进行多少次操作。
如果我们从前往后考虑数组是否要进行变化,第i个数进行变化,他有可能会导致他大于第i+1个数,这样可能会将变化一直往后传递。导致累计需要进行的变化越来越多。
但是如果从后往前考虑数组是否要进行变化时,第i个数进行变化会直接让前面所有数对于每个位置需要进行的操作数-1。那么这样的话,我们可以容易的统计从第n个数到第i个数最多能进行多少次变化,如果第i个数加上这些变化后任然小于第i-1个数,那么这个数组就没法变为非降序数组。
F题怎么计算最小次数。 我们可以 发现 a[i-1] a[i] 在经过一次变化之和 变为 a[i-1]+i-1 a[i]+i,他们两个之间的差值a[i]-a[i-1]变 为 a[i]-a[i-1]+1 可以发现一次操作之后就可以让相邻数的差距减小1,如果我们通过e的方法知道整个序列能满足非降序数组,那么最少次数就变为了max(a[i-1] - a[i]),这个就是他们需要通过多少次操作才能弥补这个差距个数
E题代码:
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
int t = input.nextInt();
for (int o = 0; o < t; o++) {
int n = input.nextInt();
long[] arr = new long[n + 1];
long max = 0;
for (int i = 0; i < n; i++) {
arr[i] = input.nextLong();
}
if (n % 2 == 0) out.println("YES");
else {
long cnt = 0;
boolean st = true;
for (int i = n - 1; i > 0; i--) {
if (i % 2 == 0) {
cnt += (arr[i] + cnt - arr[i - 1]) / i;
}
if (arr[i - 1] > arr[i] + cnt) {
st = false;
break;
}
}
if (st) out.println("YES");
else out.println("NO");
}
}
out.flush();
out.close();
br.close();
}
// -------------------------------- 模板 ---------------------------
public static long gcd(long a, long b) {
if (a == 0) return b;
if (b == 0) return a;
return gcd(b, a % b);
}
public static int gcd(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
return gcd(b, a % b);
}
public static long pow(long a, long b, long mod) {
long res = 1;
while (b > 0) {
if ((b & 1) == 1) res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res;
}
//
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
static Input input = new Input(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static class Input {
public BufferedReader reader;
public StringTokenizer tokenizer;
public Input(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public Double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}
}
F题代码:
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::vector<i64> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
i64 need = 0;
i64 cnt = 0;
if (n % 2 == 0) {
cnt = 2E12;
}
for (int i = n - 1; i > 0; i--) {
need = std::max(need, a[i - 1] - a[i]);
if (i % 2 == 0) {
cnt += (a[i] + cnt - a[i - 1]) / i;
}
if (a[i] + cnt < a[i - 1]) {
std::cout << -1 << "\n";
return;
}
}
std::cout << need << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}