区间众数 回滚莫队 9分 求 Hack
查看原帖
区间众数 回滚莫队 9分 求 Hack
335552
Christophe_楼主2022/2/2 14:24

RT, 随便留下一个查询区间众数的数据也好啊,蒟蒻自己调......手造不出来了......

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2e5+5,S=2e5+5;
int n,m,An,a[N],K[N],st[S],ed[S],p[N],A[N],tmp,bgtmp,cl=1,cr,bl,t,ans[N],F[N],hs[N],mnt;
inline int read() {
    register int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)){ if(ch=='-') f=-1;ch=getchar(); }
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return x*f;
}
inline void write(int x){        
    if(x<0){ putchar('-'); x=-x; }      
    if(x>9) write(x/10);     
    putchar(x%10+'0');
}
struct Node{
	int num;
	int l,r;
	bool operator<(const Node &B)const{
		return p[l]<p[B.l]||(p[l]==p[B.l]&&r<B.r);
	}
}b[N];
void Build(){
	bl=n/sqrt(m),t=(n+bl-1)/bl;
	for(int i=1;i<=n;++i){
		p[i]=(i-1)/bl+1;
		if(i<=t) st[i]=(i-1)*bl+1,ed[i]=min(n,i*bl);
	}
}
void Discrete(){
	sort(A+1,A+An+1);
	An=unique(A+1,A+An+1)-A;
	for(int i=1;i<=n;++i){
		int tp=lower_bound(A+1,A+An+1,a[i])-A;
		F[tp]=a[i],a[i]=tp;
	}
}
void Add(int i){
	++K[a[i]];
	if(K[a[i]]>tmp) tmp=a[i];
}
void ForceAdd(int i){
	++hs[a[i]];
	if(hs[a[i]]>mnt) mnt=a[i];	
}
void Mo(){
	for(int i=1;i<=m;++i){
		int pl=p[b[i].l],pr=p[b[i].r];
		if(pl==pr){
			mnt=0;
			for(int j=b[i].l;j<=b[i].r;++j) hs[a[j]]=0;
			for(int j=b[i].l;j<=b[i].r;++j) ForceAdd(j);
			ans[b[i].num]=mnt;
		}else{
			cl=ed[pl]+1;
			if(pl!=p[b[i-1].l]){
				cr=ed[pl],bgtmp=0;
				for(int j=1;j<=n;++j) K[j]=0;
			}
			tmp=bgtmp;
			while(cr<b[i].r) Add(++cr);
			bgtmp=tmp;
			while(cl>b[i].l) Add(--cl);
			ans[b[i].num]=tmp;
			while(cl<ed[pl]+1) --K[a[cl++]];
		}
	}	
}
int main(){
	An=n=read(),m=read();
	for(int i=1;i<=n;++i) A[i]=a[i]=read();
	Discrete(),Build();
	for(int i=1;i<=m;++i){
		int x=read(),y=read();
		if(x>y) swap(x,y);
		b[i].num=i,b[i].l=x,b[i].r=y;
	}
	sort(b+1,b+m+1),Mo();
	for(int i=1;i<=m;++i) write(F[ans[i]]),putchar('\n');
	return 0;
}
2022/2/2 14:24
加载中...