给出一段序列,要求任意区间内最大连续和所在的区间,首先肯定是要用线段树去解决,并不是要求直接输出和,这样一来就要麻烦一点,如果不要求输出下标,那么一段区间的最大连续和可能来自三部分,左半部分的最大连续和,右半部分的最大连续和,左半部分从最右端开始的和的最大值和右半部分从最左端开始的和的最大值的和,所以,需要每个节点需要记录本节点的最大连续和,左端开始的最大连续和,右端开始的最大连续和,而要得到父节点的左端开始的最大连续和,还需要子节点整个区间的和,所以还要记录节点整个区间的和,现在要求输出下标,那么就要记录每一个和的起始位置,在合并选择的时候就可以直接得到了,所以一个节点需要记录10项,合并的时候还要注意题目要求必须保证多解时选x较小的,再有多解时选y较小的,所以要注意合并的顺序:

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define N 500005 6 #define INF 0x80000001 7 #define L(x) x<<1 8 #define R(x) x<<1|1 9 #define max(a,b) ((a)>(b)?(a):(b)) 10 #define min(a,b) ((a)<(b)?(a):(b)) 11 int val[N]; 12 int all[N]; 13 struct node 14 { 15 int l,r; 16 int lval,rval;//左侧开始和最大值,rval类似 17 int lid,rid;//左侧开始最大和值所对应下标 18 int x,y;//最大子段和对应下标 19 int Ms;//最大子段和 20 int sum;//整段和 21 }; 22 node tree[4 * N]; 23 node getans(node ans1,node ans2) 24 { 25 node ans; 26 ans.sum = ans1.sum + ans2.sum; 27 if(ans1.lval >= ans1.sum + ans2.lval) 28 { 29 ans.lval = ans1.lval; 30 ans.lid = ans1.lid; 31 } 32 else 33 { 34 ans.lval = ans1.sum + ans2.lval; 35 ans.lid = ans2.lid; 36 } 37 if(ans2.rval > ans2.sum + ans1.rval) 38 { 39 ans.rval = ans2.rval; 40 ans.rid = ans2.rid; 41 } 42 else 43 { 44 ans.rval = ans2.sum + ans1.rval; 45 ans.rid = ans1.rid; 46 } 47 if(ans1.Ms > ans1.rval + ans2.lval) 48 { 49 ans.Ms = ans1.Ms; 50 ans.x = ans1.x; 51 ans.y = ans1.y; 52 } 53 else 54 { 55 if(ans1.Ms == ans1.rval + ans2.lval) 56 { 57 ans.Ms = ans1.Ms; 58 if(ans1.x <= ans1.rid) 59 { 60 ans.x = ans1.x; 61 ans.y = ans1.y; 62 } 63 else 64 { 65 ans.x = ans1.rid; 66 ans.y = ans2.lid; 67 } 68 } 69 else 70 { 71 ans.Ms = ans1.rval + ans2.lval; 72 ans.x = ans1.rid; 73 ans.y = ans2.lid; 74 } 75 } 76 if(ans2.Ms > ans.Ms) 77 { 78 ans.Ms = ans2.Ms; 79 ans.x = ans2.x; 80 ans.y = ans2.y; 81 } 82 return ans; 83 } 84 void build(int l,int r,int i) 85 { 86 tree[i].l = l; 87 tree[i].r = r; 88 tree[i].Ms = 0; 89 if(l == r) 90 { 91 tree[i].lval = tree[i].rval = tree[i].Ms = tree[i].sum = val[l]; 92 tree[i].x = tree[i].y = tree[i].lid = tree[i].rid = l; 93 return; 94 } 95 int mid = (l + r) >> 1; 96 int li = L(i),ri = R(i); 97 build(l,mid,li); 98 build(mid + 1,r,ri); 99 tree[i] = getans(tree[li],tree[ri]); 100 tree[i].l = l; 101 tree[i].r = r; 102 } 103 node query(int l,int r,int i) 104 { 105 node ans; 106 if(tree[i].l == l && tree[i].r == r) 107 { 108 ans = tree[i]; 109 return ans; 110 } 111 node ans1,ans2,ans3; 112 ans1.Ms = ans2.Ms = ans3.Ms = INF; 113 int li = L(i), ri = R(i); 114 int mid = (tree[i].l + tree[i].r) >> 1; 115 if(r <= mid) 116 ans1 = query(l,r,li); 117 else if(l > mid) 118 ans2 = query(l,r,ri); 119 else 120 { 121 ans1 = query(l,mid,li); 122 ans2 = query(mid + 1, r, ri); 123 } 124 if(ans1.Ms == INF) 125 return ans2; 126 else if(ans2.Ms == INF) 127 return ans1; 128 else 129 ans = getans(ans1,ans2); 130 return ans; 131 } 132 int main() 133 { 134 int n,m,i,j; 135 int a,b; 136 int tcase; 137 scanf("%d",&tcase); 138 node ans; 139 while(tcase--) 140 { 141 scanf("%d%d",&n,&m); 142 for(i = 1; i <= n; i++) 143 scanf("%d",&val[i]); 144 build(1,n,1); 145 while(m--) 146 { 147 scanf("%d%d",&a,&b); 148 ans = query(a,b,1); 149 printf("%d %d\n",ans.x,ans.y); 150 } 151 } 152 return 0; 153 }