Frequent values
题目大意:给出一个非降序的整数数组a1,a2,a3...an,你的任务是对一系列的询问(i,j),回答ai,ai+1,ai+2...aj中出现次数最多的值所出现的次数。输入包括多组数据。每组数据第一行为两个整数n和q(1<=n,q<=100000)。第二行包含n个非降序排列的整数a1,a2,a3...an(-100000<=ai<=100000),以下q行每行包括两个整数i和j(1<=i<=j<=n),输入以0结束。
解决方法:用value[i]和Count[i]分别表示第i段的数值和出现的次数,num[p],Left[p],Right[p]分别表示位置p所在段的编号和左右端点的位置,所以(i,j)的答案就是取Right[i]-i+1,j-Left[j]+1,query(1,t,1,num[i]+1,num[j]-1)的最大值。
AC代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
int arr[maxn];
int maxl[maxn];
int value[maxn];
int Count[maxn];
int Left[maxn];
int Right[maxn];
int num[maxn];
void pushup(int x)
{
maxl[x]=max(maxl[x<<1],maxl[x<<1|1]);
}
void build(int l,int r,int x)
{
if(l==r)
{
maxl[x]=Count[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,x<<1);
build(mid+1,r,x<<1|1);
pushup(x);
}
int query(int l,int r,int x,int L,int R)
{
int ans=0;
if(L<=l&&r<=R)
return maxl[x];
int mid=(l+r)>>1;
if(L<=mid)
ans=max(ans,query(l,mid,x<<1,L,R));
if(R>mid)
ans=max(ans,query(mid+1,r,x<<1|1,L,R));
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
//freopen("out.txt", "w", stdout);
ios::sync_with_stdio(0),cin.tie(0);
int n,m;
while(cin>>n&&n)
{
cin>>m;
ms(maxl);ms(arr);
ms(value);ms(Count);ms(num);ms(Left);ms(Right);
int t=0;
int l1=1,r1=n;
rep(i,1,n) {
cin>>arr[i];
if(arr[i]!=arr[i-1]||i==1)
{
t++;
if(i!=1)
l1=i;
}
num[i]=t;
Count[t]++;
value[t]=arr[i];
Left[i]=l1;
}
lep(i,n,1) {
Right[i]=r1;
if(arr[i]!=arr[i-1])
r1=i-1;
}
build(1,t,1);
while(m--)
{
int a,b;
cin>>a>>b;
if(a==b)
cout<<1<<endl;
else {
int ans=0;
ans=query(1,t,1,num[a]+1,num[b]-1);
int nape;
if(Right[a]==Right[b])
nape=b-a+1;
else
nape=max(Right[a]-a+1,b-Left[b]+1);
ans=max(ans,nape);
cout<<ans<<endl;
}
}
}
return 0;
}