Partial Sum
Accepted : 98 Submit : 391
Time Limit : 3000 MS Memory Limit : 65536 KB
Partial Sum
Bobo has a integer sequence a1,a2,…,an of length n. Each time, he selects two ends 0≤l<r≤n and add |∑rj=l+1aj|−C into a counter which is zero initially. He repeats the selection for at most m times.
If each end can be selected at most once (either as left or right), find out the maximum sum Bobo may have.
Input
The input contains zero or more test cases and is terminated by end-of-file. For each test case:
The first line contains three integers n, m, C. The second line contains n integers a1,a2,…,an.
2≤n≤105
1≤2m≤n+1
|ai|,C≤104
The sum of n does not exceed 106.
Output
For each test cases, output an integer which denotes the maximum.
Sample Input
4 1 1
-1 2 2 -1
4 2 1
-1 2 2 -1
4 2 2
-1 2 2 -1
4 2 10
-1 2 2 -1
Sample Output
3
4
2
0
Source
XTU OnlineJudge
sum[i]=∑ii=1a[i]
sum[0]=0
|∑rj=l+1a[j]|−C=|sum[r]−sum[l]|−C
显然
res=|sum[r]−sum[l]|−C,sum[r]越大,sum[l]越小,res越大
对
sum[0..n]进行排序,依次选择sum[n]−sum[0],sum[n−1]−sum[1],...sum[n−i]−sum[i],直到abs值小于C即可
#include<stdio.h>
#include <iostream>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<deque>
#include<map>
#include<set>
#include<queue>
#include<math.h>
#include<string.h>
#include<string>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int inf = 1e9 + 7;
const int N = 1e5+5;
int sum[N];
int main()
{
//freopen("/home/lu/Documents/r.txt","r",stdin);
//freopen("/home/lu/Documents/w.txt","w",stdout);
int n,m,c;
while(~scanf("%d%d%d",&n,&m,&c)){
for(int i=1;i<=n;++i){
scanf("%d",&sum[i]);
sum[i]+=sum[i-1];
}
sort(sum,sum+n+1);
ll ans=0;
for(int i=0;i<m;++i){
if(abs(sum[n-i]-sum[i])>c){
ans+=abs(sum[n-i]-sum[i])-c;
}
else{
break;
}
}
printf("%I64d\n",ans);
}
return 0;
}