机房大佬hyy有一种$O(N\sqrt(N))$的做法。
思路是这样的,先预处理出来块与块之间的最小众数。
之后将属于同一种的用vector存起它们的位置。
对于$p=q$的情况,直接暴力。
对于$p!=q$的情况,继承答案$ans=f[p+1][q-1],num=d[p+1][q-1]$,之后用玄学思路加速。

for(int i=L;i<=r[p];i++)
{
    int st=cnt[i];
    while(st+ans<v[a[i]].size()&&v[a[i]][st+ans]<=R){++ans;num=a[i];}//如果第st+ans个a[i]的位置小于等于R
    if(st+ans-1<v[a[i]].size()&&v[a[i]][st+ans-1]<=R&&a[i]<num)num=a[i];
}
for(int i=l[q];i<=R;i++)
{
    int st=cnt[i];
    while(st-ans>=0&&v[a[i]][st-ans]>=L){++ans;num=a[i];}//如果第ed-ans个a[i]的位置大于等于L,才可以
    if(st-ans+1>=0&&v[a[i]][st-ans+1]>=L&&a[i]<num)num=a[i];
}