zoukankan      html  css  js  c++  java
  • [CF86D] Powerful array

    [CF86D] Powerful array - 莫队

    Description

    给定长度为 (n) 的序列 (a),有 (q) 次询问,每次询问给出两个数 (l,r)。对于每次询问,设 (cnt_i) 表示 (i)(a_l,a_{l+1},cdots,a_r) 出现的次数,您需要求出 (displaystylesum_i cnt_i^2cdot i)(1le a_ile 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();
    }
    
  • 相关阅读:
    Hadoop概述与配置
    组件间通讯及钩子函数
    react组件
    JSX
    Node.js二分查找
    链表
    微信支付V3
    在有序数组中查找某一特定元素的索引
    给定一个只包括 ‘(‘,‘)‘,‘{‘,‘}‘,‘[‘,‘]‘ 的字符串,判断字符串是否有效。
    我的前半生
  • 原文地址:https://www.cnblogs.com/mollnn/p/14351583.html
Copyright © 2011-2022 走看看