//RMQ(線段樹求解)<br />//A這道題後,懂得了對數列的轉換,如果要求連續區間和,就必須把它轉化成SUM[I],表示從1到I的區間之和<br />//這樣的話要求任意區間的和,假設[I,J]的和,只需要sum[j] - sum[i-1]就可以立即求出來了<br />//注意sum[0] = 0;<br />//思路:枚舉從L開始到的的sum[i](i >= L)<br />//對符合長度條件的區間中找到一個最大的sum[j] (max(0,i-U) <= j <= i-L)<br />//這樣的話sum[i] - sum[j]便是最小的<br />//這樣就將問題轉化為求給定區間的最大值<br />//這道題不能用ST演算法來做,用ST會逾時,可能是在log的運算那裡花去太多時間<br />//看了別人的題解,看到有用優先隊列最佳化的,這個的速度應該更快<br />#include<iostream><br />#define MAX 32780<br />#define INF 2147483647<br />using namespace std;<br />int n,L,U;<br />int sum[MAX];<br />int _max,ans;<br />struct seg<br />{<br />int l,r,_max;<br />}segTree[MAX * 4];<br />void buildTree(int fa,int l,int r)<br />{<br />segTree[fa].l = l;<br />segTree[fa].r = r;<br />if(l == r)<br />{<br />segTree[fa]._max = sum[l];<br />return;<br />}<br />int mid = (l + r) >> 1;<br />buildTree(2*fa,l,mid);<br />buildTree(2*fa+1,mid+1,r);<br />segTree[fa]._max = max(segTree[2*fa]._max,segTree[2*fa+1]._max);<br />}<br />void search(int fa,int l,int r)<br />{<br />if(segTree[fa].l == l && segTree[fa].r == r)<br />{<br />_max = max(_max,segTree[fa]._max);<br />return;<br />}<br />int mid = (segTree[fa].l + segTree[fa].r) >> 1;<br />if(r <= mid)search(2*fa,l,r);<br />else if(l > mid)search(2*fa+1,l,r);<br />else<br />{<br />search(2*fa,l,mid);<br />search(2*fa+1,mid+1,r);<br />}<br />}<br />int main()<br />{<br />//freopen("in.txt","r",stdin);<br />while(scanf("%d",&n) && n)<br />{<br />ans = INF;<br />scanf("%d%d",&L,&U);<br />sum[0] = 0;<br />for(int i = 1;i <= n;++i)<br />{<br />scanf("%d",∑[i]);<br />sum[i] += sum[i-1];<br />}<br />buildTree(1,0,n);<br />for(int i = L;i <= n;++i)<br />{<br />_max = (-1)*INF;<br />search(1,max(0,i - U),i - L);<br />if(sum[i] - _max < ans)<br />ans = sum[i] - _max;<br />}<br />printf("%d/n",ans);<br />}<br />return 0;<br />}