(線段樹區間合併)UVA 11235 - Frequent values

題意:node

一個數列,屢次查詢L到R最多連續相同數字的數量。ios

分析:ui

顯然區間合併。不過還就沒寫了,都有點忘了。spa

不過回憶一下,push_down仍是寫對了。code

不過WA了,後來仔細想想,光查詢光用已經維護的答案還不夠,還須要在query的時候再合併一下,才能更新出正確的答案。blog

 

代碼:string

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 
 7 
 8 using namespace std;
 9 
10 const int inf = 0x3f3f3f3f;
11 const int maxn = 100010;
12 
13 struct Node {
14     int left, right;
15     int llen, rlen, zlen;
16     int lval, rval;
17 } node[maxn << 2];
18 
19 
20 
21 void push_up(int n) {
22     node[n].llen = node[n << 1].llen;
23     node[n].lval = node[n << 1].lval;
24     node[n].rlen = node[n << 1 | 1].rlen;
25     node[n].rval = node[n << 1 | 1].rval;
26     if(node[n << 1].llen == node[n << 1].right - node[n << 1].left + 1 && node[n << 1].rval == node[n << 1 | 1].lval) {
27         node[n].llen += node[n << 1 | 1].llen;
28     }
29     if(node[n << 1 | 1].rlen == node[n << 1 | 1].right - node[n << 1 | 1].left + 1 && node[n << 1].rval == node[n << 1 | 1].lval) {
30         node[n].rlen +=  node[n << 1].rlen;
31     }
32     node[n].zlen = max(node[n << 1].zlen, node[n << 1 | 1].zlen);
33     if(node[n << 1].rval == node[n << 1 | 1].lval) {
34         node[n].zlen = max(node[n].zlen, node[n << 1].rlen + node[n << 1 | 1].llen);
35     }
36 }
37 
38 void build(int n, int left, int right) {
39     node[n].left = left;
40     node[n].right = right;
41     if(left == right) {
42         scanf("%d", &node[n].lval);
43         node[n].rval = node[n].lval;
44         node[n].llen = node[n].rlen = node[n].zlen = 1;
45         return;
46     }
47     int mid = (left + right) >> 1;
48     build(n << 1, left, mid);
49     build(n << 1 | 1, mid + 1, right);
50     push_up(n);
51 }
52 
53 
54 int query(int n, int left, int right) {
55     if(node[n].left == left && node[n].right == right) {
56         return node[n].zlen;
57     }
58 //    printf("%d %d\n", node[n].left, node[n].right);
59     int mid = (node[n].left + node[n].right) >> 1;
60     int maxs = -1;
61     if(mid >= right)maxs = max(maxs, query(n << 1, left, right));
62     else if(mid < left)maxs = max(maxs, query(n << 1 | 1, left, right));
63     else {
64         int s = query(n << 1, left, mid);
65         int t = query(n << 1 | 1, mid + 1, right);
66         maxs = max(s, t);
67         int ls = min(node[n << 1].rlen, mid - left + 1);
68         int rs = min(node[n << 1 | 1].llen, right - mid);
69         if(node[n << 1].rval == node[n << 1 | 1].lval) {
70             maxs = max(maxs, ls + rs);
71         }
72     }
73 //    printf("--%d %d %d\n", node[n].left, node[n].right, maxs);
74     return maxs;
75 }
76 
77 int main() {
78 #ifndef ONLINE_JUDGE
79 //    freopen("1.in", "r", stdin);
80 //    freopen("1.out", "w", stdout);
81 #endif
82     int n, q;
83     while(~scanf("%d", &n) && n) {
84         scanf("%d", &q);
85         build(1, 1, n);
86 //        for(int i = 1; i <= 250; i++) {
87 //            printf("%d %d %d %d %d\n", node[i].left, node[i].right, node[i].llen, node[i].rlen, node[i].zlen);
88 //        }
89         while(q--) {
90             int l, r;
91             scanf("%d%d", &l, &r);
92             printf("%d\n", query(1, l, r));
93 //            puts("");
94         }
95     }
96     return 0;
97 
98 }
相關文章
相關標籤/搜索