题目大意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半

输入输出样例
输入 #1复制

7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6
输出 #1复制
1
0
3
0
4


就是很明显的主席树,我们每次查询时,看左右区间的和*2 是否大于当前我们查询的区间长度即可。

如果不满足,返回0;


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e5+10;
int n,q,root[N],cnt,x;
struct node{
	int l,r,sum;
}t[N<<5];
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;
	if(2*(t[t[y].l].sum-t[t[x].l].sum)>k)	return ask(l,mid,t[x].l,t[y].l,k);
	if(2*(t[t[y].r].sum-t[t[x].r].sum)>k)	return ask(mid+1,r,t[x].r,t[y].r,k);
	return 0;
}
signed main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++)	scanf("%d",&x),change(1,n,root[i],root[i-1],x);
	while(q--){
		int l,r; scanf("%d %d",&l,&r); 
		printf("%d\n",ask(1,n,root[l-1],root[r],r-l+1));
	}
	return 0;
}