BZOJ 3781: 小B的询问 | 莫队

题目:

 http://www.lydsy.com/JudgeOnline/problem.php?id=3781


题解:

上一道题一样的思路,平方就是先把原来减去,再把这个加上

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 50010
typedef unsigned long long ll;
using namespace std;
ll n,m,c[N],S,L,R,K;
ll ans[N],cnt[N],cur;
struct node
{
    ll l,r,bl,id;
    bool operator < (const node &x)const
    {
        return bl<x.bl || bl==x.bl && r<x.r;
    }
}q[N];
inline ll sqr(ll x){return x*x;}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&K);S=sqrt(n),cnt[0]=1;
    for (ll i=1;i<=n;i++)
    scanf("%lld",c+i);
    for (ll i=1,l,r;i<=m;i++)
    {
    scanf("%lld%lld",&q[i].l,&q[i].r);
    q[i].id=i;q[i].bl=(q[i].l-1)/S+1;
    }
    sort(q+1,q+1+m);
    for (ll i=1;i<=m;i++)
    {
    ll tl=q[i].l,tr=q[i].r;
    while (L<tl) cur-=sqr(cnt[c[L]]--),cur+=sqr(cnt[c[L++]]);
    while (L>tl) cur-=sqr(cnt[c[--L]]),cur+=sqr(++cnt[c[L]]);
    while (tr>R) cur-=sqr(cnt[c[++R]]),cur+=sqr(++cnt[c[R]]);
    while (R>tr) cur-=sqr(cnt[c[R]]--),cur+=sqr(cnt[c[R--]]);
    ans[q[i].id]=cur;
    }
    for (int i=1;i<=m;i++)
    printf("%lld\n",ans[i]+1);
    return 0;
}

 

posted @ 2018-01-03 16:48  MSPqwq  阅读(172)  评论(0编辑  收藏  举报