求助,莫队+值域分块66分,最后三个WA了
查看原帖
求助,莫队+值域分块66分,最后三个WA了
209808
银河AI楼主2021/5/8 22:44

求调,不知道哪里打假了

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1,M=320;
int n,m;
int a[N];
int bel[N],st[M],ed[M],cnt[N],tot[M],sum[M];
int ans1[N],ans2[N],maxn;
struct query{
	int l,r,a,b,id;
}q[N];
namespace blk{
	inline void init(){
		int block=M,len=ceil((double)maxn/block);
		for(int i=1;i<=len;i++){
			for(int j=(i-1)*block;j<=i*block;j++) bel[j]=i;
			st[i]=(i-1)*block,ed[i]=min(maxn,i*block);
		}
	}
	inline void add(int x){
		cnt[x]++;
		sum[bel[x]]++;
		if(cnt[x]==1) tot[bel[x]]++;
	} 
	inline void del(int x){
		cnt[x]--;
		sum[bel[x]]--;
		if(cnt[x]==0) tot[bel[x]]--;
	}
	inline void ask(int l,int r,int id){
		if(bel[l]==bel[r]){
			for(int i=l;i<=r;i++) if(cnt[i]) ans1[id]+=cnt[i],ans2[id]++;
			return ;
		} 
		for(int i=l;i<=ed[bel[l]];i++) if(cnt[i]) ans1[id]+=cnt[i],ans2[id]++;
		for(int i=st[bel[r]];i<=r;i++) if(cnt[i]) ans1[id]+=cnt[i],ans2[id]++;
		for(int i=bel[l]+1;i<=bel[r]-1;i++) ans1[id]+=sum[i],ans2[id]+=tot[i];
	}
} 
using namespace blk;
inline int cmp(query x,query y){return bel[x.l]==bel[y.l]?x.r<y.r:bel[x.l]<bel[y.l];}
int l=1,r=0;
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]),maxn=max(maxn,a[i]);
	for(int i=1;i<=m;i++) scanf("%lld%lld%lld%lld",&q[i].l,&q[i].r,&q[i].a,&q[i].b),q[i].id=i,maxn=max(maxn,q[i].r);
	init();
	sort(q+1,q+m+1,cmp);
	for(int i=1;i<=m;i++){
		int ql=q[i].l,qr=q[i].r;
		while(l<ql) del(a[l++]);
		while(l>ql) add(a[--l]);
		while(r>qr) del(a[r--]);
		while(r<qr) add(a[++r]); 
		ask(q[i].a,q[i].b,q[i].id);
	}
	for(int i=1;i<=m;i++) printf("%lld %lld\n",ans1[i],ans2[i]);
}

2021/5/8 22:44
加载中...