NC13888. Maximize The Beautiful Value++
描述
输入描述
The first line contains an positive integer T(1≤T≤10), represents there are T test cases.
For each test case:
The first line contains two positive integers n,k(1≤n≤105,1≤k<n),the length of the sequence ,the least steps you need to move.
The second line contains n integers a1,a2…an(1≤ai≤108) - the sequence.
输出描述
For each test case, you should output the max F(n).
示例1
输入:
4 5 3 1 1 3 4 5 5 2 1 1 3 4 5 5 1 1 1 3 4 5 5 3 3 5 4 1 1
输出:
46 50 53 43
说明:
In the forth example, you can move the fifth number 1 for 4 steps and then the sequence becomes [1,3,5,4,1]Java 解法, 执行用时: 755ms, 内存消耗: 33640K, 提交时间: 2023-04-04 13:29:48
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { private static long[] sum; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); long T = Integer.parseInt(br.readLine()); while (T-- > 0) { String[] reading = br.readLine().split(" "); int n = Integer.parseInt(reading[0]); int k = Integer.parseInt(reading[1]); long[] arr = new long[n + 1]; sum = new long[n + 1]; int[] queue = new int[n + 1]; long res = 0; int head = 0; int tail = 0; reading = br.readLine().split(" "); for (int i = 1; i <= n; i++) { arr[i] = Integer.parseInt(reading[i - 1]); sum[i] = sum[i - 1] + arr[i]; res += arr[i] * i; } long temp = 0; for (int i = k + 1; i <= n; i++) { while (tail - head >= 2 && cmp(queue[tail - 2], queue[tail - 1], i - k)) { tail--; } queue[tail++] = i - k; int left = head; int right = tail - 1; while (left != right) { int mid = (left + right) / 2; if (check(arr[i], queue[mid], queue[mid + 1])) { left = mid + 1; } else { right = mid; } } temp = Math.max(temp, res + sum[i - 1] - sum[queue[left] - 1] - arr[i] * (i - queue[left])); } System.out.println(temp); } } private static boolean check(long x, int i, int j) { return x * (j - i) > sum[j - 1] - sum[i - 1]; } private static boolean cmp(int i, int j, int k) { return (sum[k-1]-sum[j-1])*(j-i)<=(sum[j-1]-sum[i-1])*(k-j); } }
C++11(clang++ 3.9) 解法, 执行用时: 484ms, 内存消耗: 2020K, 提交时间: 2019-07-28 10:14:31
#include <iostream> #include <stdio.h> using namespace std; typedef long long ll; const int N=1e5+2; ll a[N],q[N],p[N]; ll n,k; bool judge(ll i,ll x1,ll x2) { if((p[x1]-p[x2])>a[i]*(x1-x2)) return true; return false; } bool judge2(ll i,ll x1,ll x2) { if((p[i]-p[x1])*(x2-x1)<(p[x2]-p[x1])*(i-x1)) return true; return false; } int main() { int t; cin>>t; while(t--) { p[0]=0;ll sum=0;ll ans=0; cin>>n>>k; for(int i=1;i<=n;i++ ) { cin>>a[i]; p[i]=p[i-1]+a[i]; sum+=a[i]*i; } int l=1;int r=1,ra=1;q[1]=0; for(int i=1+k;i<=n;i++) { r=ra; l=1; while(l<r-1) { int mid=(l+r)/2; if(judge(i,q[mid],q[mid+1])) l=mid; else r=mid-1; } if((l==ra)||(!judge(i,q[l],q[l+1])))l--; ans=max(ans,sum+p[i]-p[q[l+1]]-a[i]*(i-q[l+1])); while(1<ra&&judge2(i-k,q[ra-1],q[ra]))ra--; q[++ra]=i-k; } cout <<ans<< endl; } return 0; }