luogu P1997 faebdc的烦恼 | 莫队

离散化+莫队

cnt数组表示某个颜色出现的次数

sum数组表示某个数量出现的颜色种类数

其它细节问题就按照莫队的模板来的

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
const int N=1e7+10;
struct E{
	int l,r,id;
}e[N*2];
int belong[N];
bool cmp(E a,E b){
	return (belong[a.l]^belong[b.l]) ? a.l<b.l : a.r<b.r;
}
int a[N];
int cnt[N],sum[N],op;
inline void add(int x){
	cnt[a[x]]++;
	sum[cnt[a[x]]]++;
	op=max(cnt[a[x]],op);
}
inline void del(int x){
	sum[cnt[a[x]]]--;
	if(sum[cnt[a[x]]]==0)op--;
	cnt[a[x]]--;
}
int ans[N];
int w[N];
int main(){
	int n,q;
	cin>>n>>q;
	int size=sqrt(n*2.0/3.0);
	int num=ceil((double)n/size);
	for(int i=1;i<=num;i++)
	for(int j=(i-1)*size+1;j<=i*size;j++)
	belong[j]=i;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		w[i]=a[i];
	}
	sort(w+1,w+1+n);
	int len=unique(w+1,w+n+1)-w-1;//去重
	for(int i=1;i<=n;i++)
	a[i]=lower_bound(w+1,w+1+len,a[i])-w;//离散化

	for(int i=1;i<=q;i++){
		scanf("%d%d",&e[i].l,&e[i].r);
		e[i].l=max(1,e[i].l);
		e[i].l=min(n,e[i].l);
		e[i].r=max(1,e[i].r);
		e[i].r=min(n,e[i].r);
		e[i].id=i;
	}
	sort(e+1,e+1+q,cmp);
	int l=e[1].l,r=e[1].r;
	for(int i=l;i<=r;i++)add(i);
	for(int i=1;i<=q;i++){
		while(l<e[i].l)del(l++);
		while(l>e[i].l)add(--l);
		while(r<e[i].r)add(++r);
		while(r>e[i].r)del(r--);
		ans[e[i].id]=op;
	}
	for(int i=1;i<=q;i++){
		printf("%d\n",ans[i]);
	}
}
posted @ 2019-08-08 19:47  白木偶君  阅读(167)  评论(3编辑  收藏  举报