POJ 3368 Frequent values RMQ / 线段树
来源:互联网 发布:压缩文件加密破解软件 编辑:程序博客网 时间:2024/05/19 03:43
题意;给定一个升序的数列(1-100000), 比如 array[10] = -1 -1 1 1 1 1 3 10 10 10, 求其中某段区间上相同的数字最多有几个。[ 2, 3 ] = 1, [ 1, 10 ] = 4, [ 5, 10 ] = 3。(下标从1开始)。
题解:先将连续相等的几个数合并为一个部分(part), 或者说一个点。每点包括了起始位置,终止位置,相等元素个数三个信息。
查询的时候需要整点的查询,假设对区间 [ a, b ] 查询 ( [ a, b ] 里可能包含了多个点 ), 若 a, b 均不是点的边界位置,那么就需要进行处理。
例如前面的数列求 [ 5, 10 ], 我们已经知道 { -1, -1 } = 点 1, { 1,1,1,1 } = 点2, { 3 } = 点3, { 10,10,10 } = 点4。array[5]属于点2但不是点的边界,那么将 5 - 6 取出来单独讨论,然后再查询点3,点4。
#include <iostream>using namespace std;#define N 1000000#define M 100005int array[M], hash[M];/* hash表示每一个数字所属的part */struct partition{int s, t, cnt;} part[M];struct item{int l, r, num;} node[N];int max ( int a, int b ){return a > b ? a : b;}void build_tree ( int l, int r, int u ){node[u].l = l;node[u].r = r;if ( l == r ){node[u].num = part[l].cnt;return;}int mid = ( l + r ) / 2;build_tree ( l, mid, u * 2 );build_tree ( mid + 1, r, u * 2 + 1 );node[u].num = max ( node[u*2].num, node[u*2+1].num );}int query ( int l, int r, int u ){if ( node[u].l == l && node[u].r == r )return node[u].num;int mid = ( node[u].l + node[u].r ) / 2;if ( r <= mid )return query ( l, r, u * 2 );else if ( l > mid )return query ( l, r, u * 2 + 1 );elsereturn max ( query(l,mid,u*2), query(mid+1,r,u*2+1) );}int main(){int n, q;int i, id, a, b, num1, num2, num3;//freopen("a.txt","r",stdin);while ( scanf("%d",&n) && n ){scanf("%d",&q);for ( i = 1; i <= n; ++i )scanf("%d",&array[i]);memset(part,0,sizeof(part));part[1].s = id = 1;for ( i = 1; i <= n; ++i ) / *离散化,连续相同的数字归为一个part */{part[id].cnt++;hash[i] = id;if ( array[i] != array[i+1] || i == n ){part[id].t = i;id++;part[id].s = i+1;}}build_tree ( 1, id - 1, 1 );while ( q-- ){scanf("%d%d",&a,&b);if ( hash[a] == hash[b] )printf("%d\n",b-a+1);else{num1 = part[ hash[a] ].t - a + 1;num2 = b - part[ hash[b] ].s + 1;num3 = 0;if ( hash[b] - hash[a] > 1 ) num3 = query ( hash[a] + 1, hash[b] - 1, 1 );printf("%d\n", max( max(num1,num2), num3 ) );}}}return 0;}
RMQ解法:
#include <cmath>#include <iostream>using namespace std;#define M 100010int array[M], hash[M];int dp[M][18];struct partition{int s, t, cnt;} part[M];int max ( int a, int b ){return a > b ? a : b;}void Dpmax ( int n ) { int i, j, temp; for ( i = 1; i <= n; ++i ) dp[i][0] = part[i].cnt; temp = log(n+1.0)/log(2.0); for ( i = 1; i <= temp; ++i ) for ( j = 1; j + (1<<i) - 1 <= n; ++j ) dp[j][i] = max ( dp[j][i-1], dp[j+(1<<(i-1))][i-1] ); } int getmax ( int a, int b ) { int k = (int)( log(b-a+1.0) / log(2.0) ); return max ( dp[a][k], dp[b-(1<<k)+1][k] ); } int main(){int n, q;int i, id, a, b, num1, num2, num3;//freopen("a.txt","r",stdin);while ( scanf("%d",&n) && n ){scanf("%d",&q);for ( i = 1; i <= n; ++i )scanf("%d",&array[i]);memset(part,0,sizeof(part));part[1].s = id = 1;for ( i = 1; i <= n; ++i ){part[id].cnt++;hash[i] = id;if ( array[i] != array[i+1] || i == n ){part[id].t = i;id++;part[id].s = i+1;}}Dpmax(id-1);while ( q-- ){scanf("%d%d",&a,&b);if ( hash[a] == hash[b] )printf("%d\n",b-a+1);else{num1 = part[ hash[a] ].t - a + 1;num2 = b - part[ hash[b] ].s + 1;num3 = 0;if ( hash[b] - hash[a] > 1 ) num3 = getmax ( hash[a] + 1, hash[b] - 1 );printf("%d\n", max( max(num1,num2), num3 ) );}}}return 0;}
- POJ 3368 Frequent values RMQ / 线段树
- POJ 3368 Frequent values 线段树 || RMQ
- 【POJ】3368-Frequent values(RMQ或线段树)
- POJ 3368 Frequent values(线段树/RMQ)
- poj 3368 Frequent values (RMQ或线段树)
- POJ 3368 Frequent values(RMQ/线段树区间合并)
- poj 3368 Frequent values //RMQ
- POJ 3368 Frequent Values(RMQ)
- [POJ 3368]Frequent values(RMQ)
- Frequent values - POJ 3368 RMQ
- POJ--3368--Frequent values【RMQ】
- POJ 3368 Frequent values (RMQ)
- POJ 3368 Frequent values(RMQ)
- POJ 3368 Frequent values (RMQ)
- POJ 3368 Frequent Values(RMQ)
- POJ 3368 Frequent values RMQ
- POJ 3368 Frequent values (RMQ)
- POJ 3368 Frequent values RMQ
- js中2个等号与3个等号的区别
- How to set jboss.server.log.dir in JBoss
- oracle常用命令
- STL list
- 对BLENDFUNCTION的理解
- POJ 3368 Frequent values RMQ / 线段树
- myeclipse里把html改为jsp乱码问题
- C#中的Array-数组
- zoj 1095 || hdu 1058 Humble Numbers( DP || 乱搞)
- iPhone多线程
- 博客收集
- APUE 8.3 fork function
- C#中的Array和ArrayList
- 最短路径