悬关 30分tle 莫队+值域分块
查看原帖
悬关 30分tle 莫队+值域分块
590571
_weishiqi66_楼主2024/5/22 13:42
#include <bits/stdc++.h>
using namespace std;

const int N=1E6;
int n,m,t,a[N],b[N],ans[N],pos[N];
struct que{
	int id,l,r,k;
}q[N];
int ll[N],rr[N],block[N],jsq[N],cnt[N];
void add(int x) {
	--jsq[cnt[x]];
	--block[pos[cnt[x]]];
	++block[pos[++cnt[x]]];
	++jsq[cnt[x]]; 
}
void del(int x) {
	--jsq[cnt[x]];
	--block[pos[cnt[x]]];
	++block[pos[--cnt[x]]];
	++jsq[cnt[x]];
}
bool cmp(que x,que y) {
	return pos[x.l]^pos[y.l]?x.l<y.l:(pos[x.l]&1?x.r<y.r:x.r>y.r);
}
int ask(int k) {
	int i;
	for(i=1;i<=t;i++) {
		if(k-block[i]<=0) break;
		k-=block[i];
	}
	if(i==t+1) return -1;
	for(int j=ll[i];j<=rr[i];j++) {
		if(k-jsq[j]<=0) return j;
		k-=jsq[j];
	}
	return -1;
}
int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++) b[i]=a[i]=read();
	sort(b+1,b+1+n);
	int len=unique(b+1,b+1+n) -(b+1);
	for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+len,a[i])-b;
	for(int i=1;i<=m;i++) q[i].id=i,q[i].l=read(),q[i].r=read(),q[i].k=read();
	sort(q+1,q+1+m,cmp);
	t=sqrt(n);
	for(int i=1;i<=t;i++) ll[i]=(i-1)*t+1,rr[i]=i*t;
	if(rr[t]<n) ++t,ll[t]=rr[t-1]+1,rr[t]=n; 
	for(int i=1;i<=t;i++) 
		for(int j=ll[i];j<=rr[i];j++) pos[j]=i;
	int l=q[1].l,r=l-1;
	
	for(int i=1;i<=m;i++) {
		int x=q[i].l,y=q[i].r,z=q[i].k;
		while(l>x) add(a[--l]);
		while(r<y) add(a[++r]);
		while(l<x) del(a[l++]);
		while(r>y) del(a[r--]);
		ans[q[i].id]=ask(z);
	}
	for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
	return 0;
}
2024/5/22 13:42
加载中...