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