莫队80分求卡常
查看原帖
莫队80分求卡常
376679
初星逝者楼主2024/10/10 20:30

卡不动了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m;
int a[50005];
struct Node{
	int l,r;
	int id;
	int op;
	int pre;
}qq[200005];
ll ans[50005];

inline int rd()
{
	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*10+ch-48;ch=getchar();}
	return x*f;
}

inline bool cmp(Node x,Node y){
	if(x.id!=y.id)return x.id<y.id;
	if(x.id&1)return x.r<y.r;
	return x.r>y.r;
}

ll sum=0;
int tl[50005],tr[50005];

inline void addl(int x){
	sum+=tr[x];
	tl[x]++;
}

inline void addr(int x){
	sum+=tl[x];
	tr[x]++;
}

inline void dell(int x){
	sum-=tr[x];
	tl[x]--;
}

inline void delr(int x){
	sum-=tl[x];
	tr[x]--;
}

int main(){
	n=rd();
	for(register int i=1;i<=n;i++){
		a[i]=rd();
	}
	int B=sqrt(n);
	m=rd();
	int qlen=0;
	for(register int i=1;i<=m;i++){
		int a,b,c,d;
		a=rd(),b=rd(),c=rd(),d=rd();
		qq[++qlen]={b,d,(b)/B+1,1,i};
		if(qq[qlen].l>qq[qlen].r)swap(qq[qlen].l,qq[qlen].r);
		qq[++qlen]={b,c-1,(b)/B+1,-1,i};
		if(qq[qlen].l>qq[qlen].r)swap(qq[qlen].l,qq[qlen].r);
		qq[++qlen]={a-1,d,(a-1)/B+1,-1,i};
		if(qq[qlen].l>qq[qlen].r)swap(qq[qlen].l,qq[qlen].r);
		qq[++qlen]={a-1,c-1,(a-1)/B+1,1,i};
		if(qq[qlen].l>qq[qlen].r)swap(qq[qlen].l,qq[qlen].r);
	}
	sort(qq+1,qq+1+qlen,cmp);
	int l=0,r=0;
	for(register int i=1;i<=qlen;i++){
		while(l>qq[i].l)dell(a[l--]);
		while(r<qq[i].r)addr(a[++r]);
		while(l<qq[i].l)addl(a[++l]);
		while(r>qq[i].r)delr(a[r--]);
		ans[qq[i].pre]+=sum*qq[i].op;
	}
	for(register int i=1;i<=m;i++){
		cout<<ans[i]<<"\n";
	}
	return 0;
}
2024/10/10 20:30
加载中...