Frequent values
UVA - 11235
题目传送门
题目大意:给出一个非降序的整数数组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_JUDGEfreopen("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;elsenape=max(Right[a]-a+1,b-Left[b]+1);ans=max(ans,nape);cout<<ans<<endl;}}}return 0;
}