[CF86D] Powerful array - 莫队

[CF86D] Powerful array - 莫队

Description

给定长度为 \(n\) 的序列 \(a\),有 \(q\) 次询问,每次询问给出两个数 \(l,r\)。对于每次询问,设 \(cnt_i\) 表示 \(i\) 在 \(a_l,a_{l+1},\cdots,a_r\) 出现的次数,您需要求出 \(\displaystyle\sum_i cnt_i^2\cdot i\)。\(1\le a_i\le 10^6\)

Solution

这种区间问题很显然就是莫队了,每次修改的时候我们减去原来的答案再加上新的

可能因为用了太多 vector 被卡常了,于是加了个奇偶交换

#include <bits/stdc++.h>
using namespace std;

#define int long long
vector<int> belong;

struct MoSolution
{
    vector<int> a;
    int block_size;

    struct Question
    {
        int l, r, id;
        friend bool operator<(const Question &lhs, const Question &rhs)
        {
            if (belong[lhs.l] == belong[rhs.l])
                if (belong[lhs.l] & 1)
                    return lhs.r < rhs.r;
                else
                    return lhs.r > rhs.r;
            else
                return lhs.l < rhs.l;
        }
    };

    vector<Question> questions;

    struct Bucket
    {
        static const int maxn = 1e6 + 5;

        vector<int> cnt;
        int ans;

        Bucket()
        {
            cnt.resize(maxn);
            ans = 0;
        }

        void Add(int x)
        {
            ans += 2 * cnt[x] * x + x;
            cnt[x]++;
        }

        void Dec(int x)
        {
            cnt[x]--;
            ans -= 2 * cnt[x] * x + x;
        }
    } bucket;

    vector<int> ans;
    int n, m;

    void solve()
    {
        cin >> n >> m;
        block_size = sqrt(n);

        a.resize(n + 2);
        belong.resize(n + 2);

        for (int i = 1; i <= n; i++)
            cin >> a[i];
        for (int i = 1; i <= n; i++)
            belong[i] = i / block_size;

        questions.resize(m + 2);
        ans.resize(m + 2);

        for (int i = 1; i <= m; i++)
        {
            cin >> questions[i].l >> questions[i].r;
            questions[i].id = i;
        }

        sort(&questions[1], &questions[m + 1]);

        int l = 1, r = 0;

        for (int i = 1; i <= m; i++)
        {
            int ql = questions[i].l, qr = questions[i].r;

            while (r < qr)
                bucket.Add(a[++r]);
            while (l > ql)
                bucket.Add(a[--l]);

            while (r > qr)
                bucket.Dec(a[r--]);
            while (l < ql)
                bucket.Dec(a[l++]);

            ans[questions[i].id] = bucket.ans;
        }

        for (int i = 1; i <= m; i++)
        {
            cout << ans[i] << endl;
        }
    }
};

signed main()
{
    MoSolution solution;
    solution.solve();
}
上一篇:USTC English Club Note20211229


下一篇:[ AGC002 E ] Candy Piles