线段树-区间最大连续1 NKOJ2753
结构体 node 中 l 表示左界,r 表示右界, cons_l 从左开始最大连续1, cons_r ...,max 区间最大连续1
代码
1 #include <stdio.h> 2 #include <queue> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int _N = 120000; 8 9 struct node { 10 int l, r, cons_l, cons_r, max; 11 bool full() { return cons_l == r-l+1; } 12 } T[900000]; 13 14 bool A[_N]; 15 int x, y, n, m; 16 17 void _update(int p) 18 { 19 if (T[p<<1].full()) T[p].cons_l = T[p<<1].max + T[p<<1|1].cons_l; 20 else T[p].cons_l = T[p<<1].cons_l; 21 if (T[p<<1|1].full()) T[p].cons_r = T[p<<1|1].max + T[p<<1].cons_r; 22 else T[p].cons_r = T[p<<1|1].cons_r; 23 T[p].max = max(max(T[p<<1].max, T[p<<1|1].max), T[p<<1].cons_r+T[p<<1|1].cons_l); 24 return; 25 } 26 27 void _init(int p, int l, int r) 28 { 29 T[p].l = l, T[p].r = r; 30 if (l == r) { T[p].cons_l = T[p].cons_r = T[p].max = A[l]; return; } 31 int mid = l+r >> 1; 32 _init(p<<1, l, mid), _init(p<<1|1, mid+1, r); 33 _update(p); 34 return; 35 } 36 37 int _query(int p) 38 { 39 if (x <= T[p].l && T[p].r <= y) return T[p].max; 40 int cnt = 0, mid = T[p].l+T[p].r >> 1; 41 if (x <= mid && y >= T[p].l) cnt = max(cnt, _query(p<<1)); 42 if (x <= T[p].r && y > mid) cnt = max(cnt, _query(p<<1|1)); 43 if (x <= mid && mid < y) cnt = max(cnt, min(T[p<<1].cons_r, mid-x+1) + min(T[p<<1|1].cons_l, y-mid)); 44 return cnt; 45 } 46 47 int main() 48 { 49 int i; 50 scanf("%d%d", &n, &m); 51 for (i = 1; i <= n; ++i) { 52 int tmp; 53 scanf("%d", &tmp), A[i] = tmp; 54 } 55 _init(1, 1, n); 56 for (i = 1; i <= m; ++i) { 57 scanf("%d%d", &x, &y); 58 printf("%d\n", _query(1)); 59 } 60 return 0; 61 }
题目:
P2753区间连续值 | |
|
问题描述
有一数列只有0和1构成,数列中数字个数为为n。
现在有m个形式为x y的提问,询问区间[x,y]中,最多有多少个连续的1。
对于每个询问,请你快速做出回答
输入格式
第一行,两个整数n和m
第二行,n个空格间隔的数字,表示数列
接下来m行,每行两个空格间隔的整数x和y,表示一个询问(x<=y)
输出格式
m行,每行一个整数,对应询问的答案
样例输入
9 3
1 0 0 0 1 1 1 0 1
1 9
3 6
2 4
样例输出
3
2
0
提示
1<=n,m<=100000