对于莫队求区间平方和的疑惑
  • 板块学术版
  • 楼主封禁用户
  • 当前回复17
  • 已保存回复17
  • 发布时间2022/11/27 23:19
  • 上次更新2023/10/27 01:08:44
查看原帖
对于莫队求区间平方和的疑惑
206814
封禁用户楼主2022/11/27 23:19

这是小Z的袜子某一篇题解的AC思路:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[50005];
struct query{
    int id;
    int l, r;
    int a, b;
}q[50005];
int s[50005], ans = 0;
inline int gcd(int a, int b) {
    return b > 0 ? gcd(b, a % b) : a;
}
inline void update(int p, int add){
    ans -= s[a[p]] * s[a[p]];
    s[a[p]] += add;
    ans += s[a[p]] * s[a[p]];
}
signed main(){
    int n, m;
    scanf("%lld %lld", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
    int len = sqrt(n);
    for(int i = 1; i <= m; i++)
        scanf("%lld %lld", &q[i].l, &q[i].r), q[i].id = i;
    sort(q + 1, q + m + 1, [len](query A, query B)->bool{
        if((A.l - 1) / len + 1 == (B.l - 1) / len + 1)
            return A.r < B.r;
        return A.l < B.l;
    });
    for(int i = 1, l = 1, r = 0; i <= m; i++){
        for(; r < q[i].r; r++) update(r + 1, 1);
        for(; r > q[i].r; r--) update(r, -1);
        for(; l < q[i].l; l++) update(l, -1);
        for(; l > q[i].l; l--) update(l - 1, 1);
        if(q[i].l == q[i].r){
            q[i].a = 0, q[i].b = 1;
            continue;
        }
        q[i].a = ans - (q[i].r - q[i].l + 1);
        q[i].b = (q[i].r - q[i].l + 1) * (q[i].r - q[i].l);
        int g = gcd(q[i].a, q[i].b);
        q[i].a /= g, q[i].b /= g;
    }
    sort(q + 1, q + m + 1, [](query A, query B)->bool{
        return A.id < B.id;
    });
    for(int i = 1; i <= m; i++)
        printf("%lld/%lld\n", q[i].a, q[i].b);
    return 0;
}

我疑惑的是,为什么凭借几条update就可以求出区间平方和呢?有大佬可以给出直观一点的过程吗?

2022/11/27 23:19
加载中...