萌新妹子刚学OI三天 求调莫队+值域分块板子T了
查看原帖
萌新妹子刚学OI三天 求调莫队+值域分块板子T了
556545
_anll_楼主2024/1/14 11:06

rt,33pts,只过了第一个点,马蜂十分良好十分小清新,调了两天了求求各位dalao康康叭QAQ

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct P{
	int l,r,sum;
}pie[320];
struct Q{
	int l,r,a,b,id;
}que[1000005];
int n,m,bl,num[100005],pos[100005],cnt[100005];
int anu[1000005];
inline int read()
{
	int x = 0 , f = 1;	char ch = getchar();
	while(ch < '0' || ch > '9')	{if(ch == '-')	f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
inline bool cmp(Q x,Q y){
	if(x.l/bl!=y.l/bl) return x.l<y.l;
	if(x.l/bl&1) return x.r<y.r;
	return x.r>y.r;
}
inline void add(int x){
	cnt[num[x]]+=1;
	if(cnt[num[x]]==1) pie[pos[num[x]]].sum+=1;
}
inline void del(int x){
	cnt[num[x]]-=1;
	if(cnt[num[x]]==0) pie[pos[num[x]]].sum-=1;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	n=read();m=read();
    for(int i=1;i<=127;i++) pie[i].l=2147483647;
	bl=sqrt(n);
	for(int i=1;i<=n;i++){
		num[i]=read();
		pos[i]=(i-1)/bl+1;
		pie[pos[i]].l=min(pie[pos[i]].l,i);
		pie[pos[i]].r=max(pie[pos[i]].r,i);
	}
	for(int i=1;i<=m;i++){
		que[i].l=read();que[i].r=read();que[i].a=read();que[i].b=read();
		que[i].id=i;
	}
	sort(que+1,que+1+m,cmp);
	int ll=1,rr=0,ans=0;
	for(int k=1;k<=m;k++){
        int a=que[k].a,b=que[k].b,l=que[k].l,r=que[k].r,id=que[k].id;
		ans=0;
		while(ll<l) del(ll++);
		while(ll>l) add(--ll);
		while(rr<r) add(++rr);
		while(rr>r) del(rr--);
		if(pos[a]==pos[b]){
			for(int i=a;i<=b;i++) ans+=(cnt[i]>0);
		}
		else{
			for(int i=a;i<=pie[pos[a]].r;i++) ans+=(cnt[i]>0);
			for(int i=pie[pos[b]].l;i<=b;i++) ans+=(cnt[i]>0);
			for(int i=pos[a]+1;i<=pos[b]-1;i++) ans+=pie[i].sum;
		}
		anu[id]=ans;
	}
	for(int i=1;i<=m;i++) cout<<anu[i]<<endl;
	return 0;
}
2024/1/14 11:06
加载中...