题解:

吧询问变成前缀形式

然后莫队

代码:

#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;
}

 

posted on 2018-04-05 13:48  宣毅鸣  阅读(98)  评论(0编辑  收藏  举报