Max Sum of Max-K-sub-sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8462 Accepted Submission(s): 3111
Problem Description
Given a circle sequence A[1],A[2],A[3]......A[n]. Circle sequence means the left neighbour of A[1] is A[n] , and the right neighbour of A[n] is A[1].
Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases.
Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
Output
For each test case, you should output a line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.
Sample Input
4
6 3
6 -1 2 -6 5 -5
6 4
6 -1 2 -6 5 -5
6 3
-1 2 -6 5 -5 6
6 6
-1 -1 -1 -1 -1 -1
Sample Output
7 1 3
7 1 3
7 6 2
-1 1 1
题目链接:HDU 3415
把原数组复制一接到末尾,完成了从环到链的转换,然后用差分的思想,用$presum[r]-presum[l-1]$表示区间的和,那只要对于每一个$presum[r]$,找到在他前面的连续k个$presum[j]$中的最小值即可,其中用单调队列可以优化到O(N)的复杂度
代码:
#include <stdio.h> #include <iostream> #include <algorithm> #include <cstdlib> #include <cstring> #include <bitset> #include <string> #include <stack> #include <cmath> #include <queue> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) #define fin(name) freopen(name,"r",stdin) #define fout(name) freopen(name,"w",stdout) #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); typedef pair<int, int> pii; typedef long long LL; const double PI = acos(-1.0); const int N = 200010; int arr[N], pre[N]; int main(void) { int T, n, k, i; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &k); for (i = 1; i <= n; ++i) { scanf("%d", &arr[i]); arr[n + i] = arr[i]; } int nn = n << 1; for (i = 1; i <= nn; ++i) pre[i] = pre[i - 1] + arr[i]; deque<int>q; int ans = -1e9 - 7, l = 1, r = 1; for (i = 1; i <= n + k - 1; ++i) { while (!q.empty() && pre[q.back()] > pre[i - 1]) q.pop_back(); q.push_back(i - 1); while (!q.empty() && i - q.front() > k) q.pop_front(); int v = pre[i] - pre[q.front()]; if (v > ans) { ans = v; l = q.front() + 1; r = i; } else if (v == ans && q.front() + 1 < l) { l = q.front() + 1; r = i; } else if (v == ans && q.front() + 1 == l && i - q.front() < r - l + 1) r = i; } l %= n; r %= n; if (!l) l = n; if (!r) r = n; printf("%d %d %d ", ans, l, r); } return 0; }