首页 > 代码库 > poj 3368 Frequent values
poj 3368 Frequent values
Description
You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.
Input
The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the
query.
The last test case is followed by a line containing a single 0.
Output
For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.
Sample Input
10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0
Sample Output
1 4 3
好复杂的一道线段树+二分的题目,
首先把每一个不同的数看作一个点,建立线段树,然后再加上二分的处理
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; const int maxn=100000+10; struct node { int left,right,mmax; }tree[maxn*4]; int a[maxn],b[maxn],c[maxn]; void buildtree(int c,int x,int y) { tree[c].left=x; tree[c].right=y; if (x==y) { tree[c].mmax=a[x]; return; } int mid=x+(y-x)/2; buildtree(c*2,x,mid); buildtree(c*2+1,mid+1,y); tree[c].mmax=max(tree[c*2].mmax,tree[c*2+1].mmax); } int get_max(int c,int x,int y) { if (tree[c].left==x && tree[c].right==y) return tree[c].mmax; int mid=tree[c].left+(tree[c].right-tree[c].left)/2; if (y<=mid) return get_max(c*2,x,y); else if (x>mid) return get_max(c*2+1,x,y); else return max(get_max(c*2,x,mid),get_max(c*2+1,mid+1,y)); } int unique(int n) { int cut=1,j=1; int ans=1; c[1]=b[1]; for(int i=2;i<=n;i++) { if (b[i]==c[j]) ans++; else { a[j]=ans; ans=1; c[++j]=b[i]; } } a[j]=ans; return j; } int find(int x,int y,int v) { while(x<y) { int m=x+(y-x)/2; if (c[m]>=v) y=m; else x=m+1; } return x; } int bfind_down(int x,int y,int v) { while(x<y) { int m=x+(y-x)/2; if (b[m]>=v) y=m; else x=m+1; } return x; } int bfind_up(int x,int y,int v) { while(x<y) { int m=x+(y-x)/2; if (b[m]<=v) x=m+1; else y=m; } return x; } int main() { int n,m,x,y; while (scanf("%d",&n)!=EOF && n) { scanf("%d",&m); for (int i=1;i<=n;i++) scanf("%d",&b[i]); int nown=unique(n); buildtree(1,1,nown); for (int i=1;i<=m;i++) { scanf("%d%d",&x,&y); if (b[x]==b[y]) {printf("%d\n",y-x+1);continue;} int xx=find(1,nown,b[x]); int yy=find(1,nown,b[y]); if (yy-xx==1){ int dx=bfind_up(1,n,b[x]); if (b[dx]>b[x]) dx--; int dy=bfind_down(1,n,b[y]); dx=dx-x+1; dy=y-dy+1; printf("%d\n",max(dx,dy)); continue; } xx++,yy--; int dx=bfind_up(1,n,b[x])-x; int dy=y-bfind_down(1,n,b[y])+1; printf("%d\n",max(get_max(1,xx,yy),max(dx,dy))); } } return 0; }
作者 chensunrise