作业

莫队+套路值域分块。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int len=305;
int n,m,a[maxn],cnt[maxn],sum[maxn],ans[maxn];
int laz[maxn],anss[maxn],lft[maxn],rht[maxn];
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
struct node{
	int l,r,a,b,bl,id;
}q[maxn];
inline int cmp(node x,node y){
	return x.bl==y.bl?x.r<y.r:x.bl<y.bl;
}
inline int query(int x,int y){
	int tot=0;
	for(int i=x;i<=y&&i<=rht[x/len];i++)
		tot+=cnt[i];
	if(y<=rht[x/len])return tot;
	for(int i=x/len+1;rht[i]<y;i++)
		tot+=sum[i];
	for(int i=lft[y/len];i<=y;i++)
		tot+=cnt[i];
	return tot;
}
inline int quest(int x,int y){
	int tot=0;
	for(int i=x;i<=y&&i<=rht[x/len];i++)
		if(cnt[i])tot++;
	if(y<=rht[x/len])return tot;
	for(int i=x/len+1;rht[i]<y;i++)
		tot+=laz[i];
	for(int i=lft[y/len];i<=y;i++)
		if(cnt[i])tot++;
	return tot;
}
inline void del(int x){
	cnt[a[x]]--;
	sum[a[x]/len]--;
	laz[a[x]/len]-=!cnt[a[x]];
}
inline void add(int x){
	laz[a[x]/len]+=!cnt[a[x]];
	cnt[a[x]]++;
	sum[a[x]/len]++;
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	for(int i=0;i<=350;i++){
		lft[i]=i*len;
		rht[i]=(i+1)*len-1;
	}
	for(int i=1;i<=m;i++){
		q[i].id=i;
		q[i].l=read(),q[i].r=read();
		q[i].a=read(),q[i].b=read();
		q[i].bl=q[i].l/len;
	}
	sort(q+1,q+1+m,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		while(l<q[i].l)del(l++);
		while(l>q[i].l)add(--l);
		while(r<q[i].r)add(++r);
		while(r>q[i].r)del(r--);
		ans[q[i].id]=query(q[i].a,q[i].b);
		anss[q[i].id]=quest(q[i].a,q[i].b);
	}
	for(int i=1;i<=m;i++)
		printf("%d %d\n",ans[i],anss[i]);
	return 0;
}

深深地感到自己的弱小。

posted @ 2020-05-28 21:21  syzf2222  阅读(102)  评论(0编辑  收藏  举报