题解:
吧询问变成前缀形式
然后莫队
代码:
#include<bits/stdc++.h> const int N=50005; using namespace std; struct ques{int l,r,id,ad;}q[N*4]; int n,block[N],size,a[N],num1[N],num2[N],m,tot=0,L=0,R=0; long long res=0,Ans[N]; bool cmp(const ques&a,const ques&b){return block[a.l]==block[b.l]?a.r<b.r:a.l<b.l;} int main() { scanf("%d",&n); size=sqrt(n); for (int i=1;i<=n;i++)block[i]=(i-1)/size+1; for (int i=1;i<=n;i++)scanf("%d",&a[i]); scanf("%d",&m); for (int i=1;i<=m;i++) { int l1,r1,l2,r2; scanf("%d%d%d%d",&l1,&r1,&l2,&r2); q[++tot]=(ques){r1,r2,i,1}; q[++tot]=(ques){r1,l2-1,i,-1}; q[++tot]=(ques){l1-1,r2,i,-1}; q[++tot]=(ques){l1-1,l2-1,i,1}; } sort(q+1,q+tot+1,cmp); for (int i=1;i<=tot;i++) { while (L<q[i].l)++L,res+=num2[a[L]],++num1[a[L]]; while (L>q[i].l)res-=num2[a[L]],--num1[a[L]],--L; while (R<q[i].r)++R,res+=num1[a[R]],++num2[a[R]]; while (R>q[i].r)res-=num1[a[R]],--num2[a[R]],--R; Ans[q[i].id]+=q[i].ad*res; } for (int i=1;i<=m;++i) printf("%lld\n",Ans[i]); return 0; }