#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<math.h>
#include<set>
using namespace std;
typedef long long ll;
const int maxx=50010;
int a[maxx];
int block;
ll sum[maxx], ans[maxx], ct = 0;
struct node
{
int l, r, num;
}p[maxx];
bool cmp(node a, node b)
{
if (a.r / block == b.r / block)//如果左端点在同一块,按右排序,否则按左
{
return a.l < b.l;
}
else
return a.r < b.r;
}
void add(int x)
{
sum[a[x]]++;
ct += 2 * sum[a[x]] - 1;
}
void del(int x)
{
sum[a[x]]--;
ct -= 2 * sum[a[x]] + 1;
}
int main()
{
int n, m, k;
cin >> n >> m >> k;
block = sqrt(n);//分块
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for (int i = 1; i <= m; i++)
{
scanf("%d%d", &p[i].l, &p[i].r);
p[i].num = i;
}
sort(p + 1, p + m + 1, cmp);
int l = 1, r = 0;
for (int i = 1; i <= m; i++)//核心代码
{
int pl = p[i].l, pr = p[i].r;
while (pl > l)
{
del(l);
l++;
}
while (pl < l)
{
l--;
add(l);
}
while (pr < r)
{
del(r);
r--;
}
while (pr > r)
{
r++;
add(r);
}
ans[p[i].num] = ct;
}
for (int i = 1; i <= m; i++)
{
printf("%lld\n", ans[i]);
}
return 0;
}
08-03
08-03
08-03
08-03