N - Frequent values
题意:给出一个非递减数组,求【L,R】区间内出现最多的数的次数。
分析:看训练指南吧。
代码:
#include <map> #include <queue> #include <vector> #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) const int maxlog=20; const int maxn=1e5+100; int n,m; int a[maxn]; int cnt[maxn],num[maxn],Left[maxn],Right[maxn]; struct RMQ { int d[maxn][maxlog]; void init(int* a,int n) { for(int i=1;i<=n;i++) d[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++){ for(int i=1;i+(1<<j)<=n;i++){ d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]); } } } int query(int L,int R) { int k=0; while((1<<(k+1))<=R-L+1) k++; return max(d[L][k],d[R-(1<<k)+1][k]); } }; RMQ rmq; int main() { // freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF&&n) { scanf("%d",&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } int tot=1,start; for(int i=1;i<=n+1;i++){ if(i==1||a[i]!=a[i-1]){ if(i>1){ cnt[tot]=i-start; for(int j=start;j<i;j++){ num[j]=tot; Left[j]=start; Right[j]=i-1; } tot++; } start=i; } } rmq.init(cnt,tot-1); for(int i=1;i<=m;i++){ int l,r,ans; scanf("%d%d",&l,&r); if(num[l]==num[r]){ ans=r-l+1; } else{ ans=max(Right[l]-l+1,r-Left[r]+1); if(num[l]+1<num[r]) ans=max(ans,rmq.query(num[l]+1,num[r]-1)); } printf("%d ",ans); } } return 0; }