(线段树区间合并)UVA 11235 - Frequent values
Posted tak_fate
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(线段树区间合并)UVA 11235 - Frequent values相关的知识,希望对你有一定的参考价值。
题意:
一个数列,多次查询L到R最多连续相同数字的数量。
分析:
显然区间合并。不过还就没写了,都有点忘了。
不过回忆一下,push_down还是写对了。
不过WA了,后来仔细想一想,光查询光用已经维护的答案还不够,还需要在query的时候再合并一下,才能更新出正确的答案。
代码:
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 }
以上是关于(线段树区间合并)UVA 11235 - Frequent values的主要内容,如果未能解决你的问题,请参考以下文章
UVA 11235 Frequent values 线段树/RMQ
UVa 11235 Frequent values (RMQ && 区间出现最多次的数的次数)
UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)
[uva11235]Frequent values(RMQ,ST,离散化)