https://www.luogu.org/blog/codesonic/Mosalgorithm
講的比較全面
針對例題寫
將詢問排序
bool cmp(node a,node b){
return pos[a.l]^pos[b.l]?pos[a.l]<pos[b.l]:pos[a.l]&1?a.r<b.r:a.r>b.r;
}
然後針對詢問操作
總複雜度O( N*sqrt(N) )
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 100;
ll bsize, rans = 0;
ll cnt[MAXN] = {0}, num[MAXN] = {0};
struct node
{
int fst, lst, id, bl;
}arr[MAXN];
bool cmp(node a, node b)
{
return a.bl != b.bl ? a.bl < b.bl : (a.bl & 1) ? a.lst < b.lst : a.lst > b.lst;
}
ll ans[MAXN] = {0};
void add(int pos)
{
rans -= cnt[num[pos]] * num[pos] * cnt[num[pos]];
++cnt[num[pos]];
rans += cnt[num[pos]] * num[pos] * cnt[num[pos]];
}
void del(int pos)
{
rans -= cnt[num[pos]] * num[pos] * cnt[num[pos]];
--cnt[num[pos]];
rans += cnt[num[pos]] * num[pos] * cnt[num[pos]];
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m;
cin >> n >> m;
bsize = sqrt(n);
for(int i = 1; i <= n; ++i)
cin >> num[i];
for(int i = 0; i < m; ++i)
{
cin >> arr[i].fst >> arr[i].lst;
arr[i].id = i;
arr[i].bl = arr[i].fst / bsize;
}
sort(arr, arr + m, cmp);
int l = 1, r = 0;
for(int i = 0; i < m; ++i)
{
while(l < arr[i].fst)
del(l++);
while(l > arr[i].fst)
add(--l);
while(r < arr[i].lst)
add(++r);
while(r > arr[i].lst)
del(r--);
ans[arr[i].id] = rans;
}
for(int i = 0; i < m; ++i)
cout << ans[i] << '\n';
return 0;
}
/*
5 5
1 2 1 2 1
1 2
2 3
2 4
2 5
3 3
*/