题意翻译
给定n个元素,m次询问。
每次给出三个参数l,r,k询问区间[l,r]内是否存在出现次数严格大于 (r - l + 1)/k
的数。如果存在就输出最小的那个ansans,否则输出-1.
输入输出样例
输入 #1复制
4 2
1 1 2 2
1 3 2
1 4 2
输出 #1复制
1
-1
输入 #2复制
5 3
1 2 1 3 2
2 5 3
1 2 3
5 5 2
输出 #2复制
2
1
2
很水的主席树,k是对于原始给出的区间来说的,每次左右看一下,优先往左转移就好了,如果都不能转移直接返回-1.
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10;
int n,q,a[N],rt[N],cnt;
struct node{int l,r,sum;}t[N*20];
void change(int l,int r,int &x,int y,int k){
x=++cnt; t[x]=t[y]; t[x].sum++;
if(l==r) return ; int mid=l+r>>1;
if(k<=mid) change(l,mid,t[x].l,t[y].l,k);
else change(mid+1,r,t[x].r,t[y].r,k);
}
int ask(int l,int r,int x,int y,int k){
if(l==r) return l; int mid=l+r>>1,res;
int ls=t[t[x].l].sum-t[t[y].l].sum,rs=t[t[x].r].sum-t[t[y].r].sum;
if(ls>k) if((res=ask(l,mid,t[x].l,t[y].l,k))>0) return res;
if(rs>k) if((res=ask(mid+1,r,t[x].r,t[y].r,k))>0) return res;
return -1;
}
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),change(1,n,rt[i],rt[i-1],a[i]);
while(q--){
static int l,r,k; scanf("%d %d %d",&l,&r,&k);
printf("%d\n",ask(1,n,rt[r],rt[l-1],(r-l+1)/k));
}
return 0;
}