• bzoj5016


    题解:

    吧询问变成前缀形式

    然后莫队

    代码:

    #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
    ",Ans[i]);
        return 0;
    }
  • 相关阅读:
    【NOIP模拟】排序
    【NOIP模拟】企鹅矩阵
    【NOIP模拟】花花森林
    【BZOJ1045】糖果传递
    【BZOJ1271】秦腾的教学评估
    【POJ3714】Raid
    【TYVJ1424】占卜DIY
    【POJ3190】The Pilots Brothers' refrigerator
    【HDU1055】Color a Tree
    【NOIP2012】国王游戏
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8722258.html
Copyright © 2020-2023  润新知