#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
const int maxn = 5 * 1e5 + 7;
//
typedef long long int ll;
struct SgTree
{
pair<ll, ll> sub; //最大和下标
ll prefix; //前缀下标
ll suffix; //后缀下标
ll l; //最大前缀和
ll r; //最大后缀和
ll sum; //所有元素和
ll max; //最大和
}tree[maxn << 2];
ll n,m,input[maxn];
void Init() {
memset(tree, 0, sizeof(tree));
memset(input, 0, sizeof(input));
}
SgTree update(SgTree& left, SgTree& right) {
SgTree ret;
//元素和
ret.sum = left.sum + right.sum;
//最大前缀
if (left.sum + right.l > left.l) {
ret.l = left.sum + right.l;
ret.prefix = right.prefix;
}
else {
ret.l = left.l;
ret.prefix = left.prefix;
}
//最大后缀
if (left.r + right.sum >= right.r) {
ret.r = left.r + right.sum;
ret.suffix = left.suffix;
}
else {
ret.r = right.r;
ret.suffix = right.suffix;
}
//最大和
ll sum = left.r + right.l;
if ((left.max >= right.max) && (left.max >= sum)) {
ret.max = left.max;
ret.sub = left.sub;
}
else if ((sum >= left.max) && (sum >= right.max)){
ret.max = sum;
ret.sub = make_pair(left.suffix,right.prefix);
}else{
ret.max = right.max;
ret.sub = right.sub;
}
return ret;
}
void build(int left, int right,int cur) {
if (left == right) {
tree[cur].sub = make_pair(left, right);
tree[cur].suffix = tree[cur].prefix = left;
tree[cur].l = tree[cur].r = tree[cur].sum = tree[cur].max = input[left];
return;
}
int mid = (left + right) >> 1;
build(left, mid, cur * 2);
build(mid + 1, right, cur * 2 + 1);
tree[cur] = update(tree[cur *2],tree[cur * 2 + 1]);
}
SgTree _Query(int a, int b,int x,int y, int cur) {
if (x >= a && y <= b) return tree[cur];
int mid = (x + y) >> 1;
SgTree left, right;
int l = 0, r = 0;
if (a <= mid) {
left = _Query(a,b,x,mid,cur*2);
l++;
}
if (b > mid) {
right = _Query(a, b, mid + 1,y, cur * 2 + 1);
r++;
}
if (l && r) return update(left, right);
else if (l) return left;
return right;
}
SgTree Query(int a, int b) {
return _Query(a, b,1,n, 1);
}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); return nullptr; }();
int main()
{
int a,b,kCase = 0;
while (cin >> n >> m) {
Init();
for (int i = 1; i <= n; i++) {
cin >> input[i];
}
build(1, n, 1);
cout << "Case " << ++kCase << ":" << endl;
for (int i = 0; i < m; i++) {
cin >> a >> b;
SgTree ans = Query(a, b);
cout << ans.sub.first << " " << ans.sub.second << endl;
}
}
return 0;
}
08-02
1436