传送门
题目:给你n个数,每个数为ai,现在有m个询问,每个询问l,r,需要求出:
代表ai在这个区间中出现的次数。
题解:莫队模板题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int n, m;
int a[N];
struct node{
int num, l, r, k;
bool operator < (const node& no) const{
if(k == no.k) return r < no.r;
else return k < no.k;
}
}e[N];
int vis[N];
ll ans[N];
ll res = 0;
void add(int x){
res -= 1ll*vis[x]*vis[x]*x;
vis[x]++;
res += 1ll*vis[x]*vis[x]*x;
}
void del(int x){
res -= 1ll*vis[x]*vis[x]*x;
vis[x]--;
res += 1ll*vis[x]*vis[x]*x;
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
int b = sqrt(n);
for(int i = 1; i <= m; i++){
scanf("%d%d", &e[i].l, &e[i].r);
e[i].num = i, e[i].k = e[i].l / b;
}
sort(e+1, e+1+m);
int l = 1, r = 0;
for(int i = 1; i <= m; i++){
while(r < e[i].r) add(a[++r]);
while(r > e[i].r) del(a[r--]);
while(l < e[i].l) del(a[l++]);
while(l > e[i].l) add(a[--l]);
ans[e[i].num] = res;
}
for(int i = 1; i <= m; i++){
printf("%lld\n", ans[i]);
}
return 0;
}