Codeforces - Destiny

题意翻译
给定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;
}
发布了416 篇原创文章 · 获赞 228 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103889461
今日推荐