Frequent values(线段树+离散化)
2014-02-20 16:45
369 查看
http://poj.org/problem?id=3368
题意:给出一个非降序排列的整数数组,对于询问(i,j),输出区间[i,j]中出现最多的值的次数。
思路:经典的RMQ,不过我用线段树做的。首先要离散化,因为是非降序的,所以相同的数是连续的,可以将相同的数分在同一个块中,将块中的信息存储起来,然后将其看成一个点,就可以用线段树进行查询了。
View Code
题意:给出一个非降序排列的整数数组,对于询问(i,j),输出区间[i,j]中出现最多的值的次数。
思路:经典的RMQ,不过我用线段树做的。首先要离散化,因为是非降序的,所以相同的数是连续的,可以将相同的数分在同一个块中,将块中的信息存储起来,然后将其看成一个点,就可以用线段树进行查询了。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N=1000010; struct node { int l,r; int Max; } Tree[N*4]; struct point//记录每块的信息 { int s,t;//s起始位置,t结束位置 int cnt;//块中的数出现的次数 } block ; int v ,num ;//num[i]表示第i个数被分在第几块 void build(int l,int r,int rt) { Tree[rt].l = l; Tree[rt].r = r; if (l==r) { Tree[rt].Max = block[l].cnt; return ; } int mid = (l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); Tree[rt].Max=max(Tree[rt<<1].Max,Tree[rt<<1|1].Max); } int Query(int l,int r,int rt) { if(Tree[rt].l==l&&Tree[rt].r==r) return Tree[rt].Max; int mid=(Tree[rt].l+Tree[rt].r)>>1; if (r <= mid) return Query(l,r,rt<<1); else if (l > mid) return Query(l,r,rt<<1|1); else return max(Query(l,mid,rt<<1),Query(mid+1,r,rt<<1|1)); } int main() { int n,q; while(~scanf("%d%d",&n,&q)&&n) { memset(block,0,sizeof(block)); for (int i = 1; i <= n; i++) scanf("%d",&v[i]); int m=1; block[m].s=1; for (int i = 1; i <= n; i++)//将相同的数分在同一块 { num[i]=m; if(v[i]!=v[i+1]||i==n) { block[m].t = i; block[m].cnt=block[m].t-block[m].s+1; block[++m].s = i+1; } } build(1,m-1,1);//将每一块看成一个点,建树 while(q--) { int l,r; scanf("%d%d",&l,&r); if (num[l]==num[r])//在同一个块里,则[l,r]是连续的相同的数 printf("%d\n",r-l+1); else //不在同一个块里 { int cnt1 = block[num[l]].t-l+1;//l所在块中,区间[l,block[num[l]].t]中相同的数的次数 int cnt3 = r-block[num[r]].s+1;//r所在块中,区间[block[num[r]].s,r]中相同的数的次数 int cnt2 = 0; if (num[r]-num[l]>1)//大于两个块 cnt2 = Query(num[l]+1,num[r]-1,1);//中间块相同数出现的最多次数 int ans = max(max(cnt1,cnt3),cnt2); printf("%d\n",ans); } } } return 0; }
View Code
相关文章推荐
- POJ 3368 Frequent values(线段树+离散化)
- poj 3368 Frequent values(离散化+线段树区间求最值)
- poj 3368 Frequent values(线段树+离散化) -
- HDU 1806 Frequent values(线段树+离散化+二分)
- POJ3368-Frequent values-离散化+线段树
- poj 3368 Frequent values 线段树 离散化
- Frequent values(线段树+离散化)
- 区间离散化+线段树区间求最值poj 3368 Frequent values
- POJ 2528 Mayor's posters 离散化+线段树
- poj1151&hdu1542Atlantis(线段树+离散化+线扫描 VS 二维线段树)
- POJ-1177-Picture(线段树+扫描线+离散化)[矩形周长并]
- poj 2528(线段树 + 离散化)
- poj 2528 线段树数据离散化+区间更新
- poj2299Ultra-QuickSort【线段树求逆序数】离散化
- hdu4288 Coder 离线线段树 单点更新 区间求和 离散化?
- POJ 2528 Mayor's posters - 线段树区间更新+离散化
- ural1019Line Painting(离散化,线段树)
- poj 2528 Mayor's posters(线段树+区间离散化)
- hihocoder1079(线段树+离散化)
- poj 2528 Mayor's posters(线段树+离散化)