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] << ' '; return 0; } /* 5 5 1 2 1 2 1 1 2 2 3 2 4 2 5 3 3 */