萌新刚学分块,卡常求调
查看原帖
萌新刚学分块,卡常求调
211086
bsTiat楼主2022/2/10 17:32

评测记录

莫队套分块做法,块长均为n/sqrt(m),试过一些其他块长,也试过莫队分块的块长不同,但是发现这样相对最快,第8个点时限1s,T了,第9个点时限3s,我200ms跑完,88分求调。

#include<bits/stdc++.h>
using namespace std;
const int N = 100005;
inline int rd(){
	char c=getchar();int sum=0,f=1;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c<='9'&&c>='0'){sum=(sum<<3)+(sum<<1)+(c^48);c=getchar();}
	return sum*f;
}
int sum[N],sump[N],sumr[N];
int n,m,a[N],len,ans[N],res[N],bl[N];
struct node{
	int l,r,a,b,id;
	bool operator<(const node& x)const{
		if(bl[l]==bl[x.l])
			if(bl[l]&1)return r<x.r;
			else return r>x.r;
		else return bl[l]<bl[x.l];
	}
}ask[N];
//sump[i]存数字i的出现次数 
//sum[i]存第i块中的数码个数
//sumr[i]存第i块中的数的个数 
void del(int x){
	x=a[x];
	--sump[x];--sumr[bl[x]];
	if(sump[x]<=0)--sum[bl[x]];
}
void add(int x){
	x=a[x];
	++sump[x];++sumr[bl[x]];
	if(sump[x]<=1)++sum[bl[x]];
}
int get_res(int l,int r){
	if(l>r)return 0;
	int ans=0;
	if(bl[l]==bl[r]){
		for(int i=l;i<=r;++i)ans+=(bool)sump[i];
		return ans;
	}
	for(int i=l;bl[i]==bl[l];++i)ans+=(bool)sump[i];
	for(int i=r;bl[i]==bl[r];--i)ans+=(bool)sump[i];
	for(int i=bl[l]+1;i<=bl[r]-1;++i)ans+=sum[i];
	return ans;
}
int get_ans(int l,int r){
	if(l>r)return 0;
	int ans=0;
	if(bl[l]==bl[r]){
		for(int i=l;i<=r;++i)ans+=sump[i];
		return ans;
	}
	for(int i=l;bl[i]==bl[l];++i)ans+=sump[i];
	for(int i=r;bl[i]==bl[r];--i)ans+=sump[i];
	for(int i=bl[l]+1;i<=bl[r]-1;++i)ans+=sumr[i];
	return ans;
}
signed main(){
	int l=1,r=0;
	n=rd();m=rd();len=1.0*n/pow(m,0.5)+1;
	for(int i=1;i<=N;++i)bl[i]=(i-1)/len+1;
	for(int i=1;i<=n;++i)a[i]=rd();
	for(int i=1;i<=m;++i){
		ask[i].l=rd();ask[i].r=rd();
		ask[i].a=rd();ask[i].b=rd();
		ask[i].id=i;
	}
	sort(ask+1,ask+1+n);
	for(int i=1;i<=m;++i){
		while(l<ask[i].l)del(l++);
		while(l>ask[i].l)add(--l);
		while(r>ask[i].r)del(r--);
		while(r<ask[i].r)add(++r);
		ans[ask[i].id]=get_ans(ask[i].a,ask[i].b);
		res[ask[i].id]=get_res(ask[i].a,ask[i].b);
	}
	for(int i=1;i<=m;++i)
		printf("%d %d\n",ans[i],res[i]);
	return 0;
}
2022/2/10 17:32
加载中...