POJ3668——Frequent values(线段树,RMQ,ST表)
来源:互联网 发布:php 判断是否正整数 编辑:程序博客网 时间:2024/05/16 17:07
题意:找一段区间内出现最多的树的个数
思路:我们只关心每个数的个数。所以把每个数的个数用一个新数组保存起来。查询的时候查询一下区间最大值即可。
RMQ查询可以用线段树树状数组或者ST表。其中ST表的查询是O(1)的复杂度。
代码提供了ST表和线段树的函数。
#include <cmath>#include <cstring>#include <cstdio>#include <vector>#include <string>#include <algorithm>#include <string>#include <map>#include <queue>#include <set>#include <stack>using namespace std;#define MAXN 500010#define LEN 200010#define INF 1e9+7#define MODE 1000000#define pi acos(-1)#define g 9.8typedef long long ll;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n,m,q;struct node{ int num; int len; int first; int last;};node ans[MAXN];int a[MAXN];int b[MAXN];int F[MAXN][20];void SparseTable(){for (int i = 0;i<m;i++){F[i][0]=ans[i].len;}int nLog = int(log(double(m))/log(2.0));for (int j = 1;j <= nLog;j++){for (int i = 0;i < m;i++){if ((i + (1 << j) - 1) < m){if(F[i][j-1]>F[i+(1<<(j-1))][j-1]) { F[i][j]=F[i][j-1]; } else { F[i][j]=F[i+(1<<(j-1))][j-1]; }}}}}int RMQ(int nStart,int nEnd){int nLog = (int)(log(double(nEnd - nStart + 1)/log(2.0)));return max(F[nStart][nLog],F[nEnd - (1 << nLog) + 1][nLog]);}#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[MAXN<<2];void PushUp(int rt){sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt){if(l==r){sum[rt]=ans[l].len;return;}int m=(l+r)>>1;build(lson);build(rson);PushUp(rt);}int query(int L,int R,int l,int r,int rt){if(L<=l&&r<=R)return sum[rt];int m=(l+r)>>1;int ret=0;if(L<=m)ret=max(ret,query(L,R,lson));if(R>m)ret=max(ret,query(L,R,rson));return ret;}int main(){ //freopen("out.txt","w",stdout); while(scanf("%d)",&n)) { if(n==0) break; scanf("%d",&q); for(int i=0;i<n;i++) { scanf("%d",a+i); ans[i].len=0; } m=0; ans[0].num=a[0]; ans[0].len=1; ans[0].first=0; for(int i=1;i<n;i++) { if(a[i]==a[i-1]) { ans[m].len++; b[i]=m; } else { ans[m].last=i-1; m++; b[i]=m; ans[m].num=a[i]; ans[m].len=1; ans[m].first=i; } } ans[m++].last=n-1; build(0,m-1,1); while(q--) { int r,l; int R,L; scanf("%d%d",&l,&r); l--; r--; L=b[l]; R=b[r]; if(R==L) { printf("%d\n",r-l+1); continue; } if(ans[L].first<l) L++; if(ans[R].last>r) R--; if(R<L) { int res=-1; res=max(res,r-ans[R+1].first+1); res=max(res,ans[L-1].last-l+1); printf("%d\n",res); continue; } int res=query(L,R,0,m-1,1); if(ans[L].first-l>res) { res=ans[L].first-l; } if(r-ans[R].last>res) { res=r-ans[R].last; } printf("%d\n",res); } }}
0 0
- POJ3668——Frequent values(线段树,RMQ,ST表)
- poj 3386 -- 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
- POJ3368 Frequent Values [RMQ] [线段树]
- UVA 11235-Frequent values-RMQ(st表)+游程编码
- UVa 11235 Frequent Values(RMQ,ST算法)
- 【RMQ|ST】POJ-3368 Frequent values
- NKOJ1752——Frequent values (运用ST算法)
- POJ3368——Frequent values(RMQ)
- UVA - 11235 —— Frequent values 【RMQ】
- UVa 11235 Frequent values / RMQ or 线段树
- poj 3368 Frequent values (RMQ或线段树)
- POJ 3368 Frequent values(RMQ/线段树区间合并)
- poj3368 Frequent values(维护个最大值rmq or 线段树)
- LeetCode-216:Combination Sum III
- C++ 程序设计_谭浩强
- RunLoop NSMachPort 详解
- javascript权威指南--关系表达式
- bzoj 3631(树链剖分)
- POJ3668——Frequent values(线段树,RMQ,ST表)
- java基础语法浅试
- 看python和莫名其妙学做网页。。。。
- 让你的网页动起来的秘诀
- 每日一记-Git的学习使用
- 洛谷1280 尼克的任务
- 深度学习概述:从感知机到深度网络
- NYOJ 28 大数阶乘
- LeetCode-35:Search Insert Position