[模板]莫队

 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
*/

 
原文地址:https://www.cnblogs.com/zeolim/p/12270330.html