• [CF703D] Mishka and Interesting sum


    [CF703D] Mishka and Interesting sum - 离线处理,树状数组

    Description

    给定 (n) 个数的序列 (a)(m) 次操作。每次求 (a_l,a_{l+1},...,a_r) 中,出现偶数次的数的异或和。

    Solution

    即区间本质不同数的异或和与区间异或和的异或,关键是求区间本质不同数的异或和

    考虑到 n 有 1e6,莫队跑不动了,考虑离线处理并用树状数组维护异或和,在每个数最后一次出现的地方放上这个数

    #include <bits/stdc++.h>
    #include <unordered_map>
    using namespace std;
    
    struct Question
    {
        int l, r, id;
        bool operator<(const Question &rhs) const
        {
            return l > rhs.l;
        }
    };
    
    struct BinaryIndexTree
    {
        int n;
        int *a;
    
        BinaryIndexTree(int n) : n(n)
        {
            a = new int[n + 2];
            fill(a, a + n + 2, 0);
        }
    
        int lowbit(int x)
        {
            return x & (-x);
        }
    
        void add(int i, int x)
        {
            while (i <= n)
            {
                a[i] ^= x;
                i += lowbit(i);
            }
        }
    
        int sum(int i)
        {
            int ans = 0;
            while (i)
            {
                ans ^= a[i];
                i -= lowbit(i);
            }
            return ans;
        }
    };
    
    inline void read(int &x)
    {
        int f = 1;
        x = 0;
        char s = getchar();
        while (!isdigit(s))
        {
            if (s == '-')
                f = -1;
            s = getchar();
        }
        while (isdigit(s))
        {
            x = x * 10 + s - '0';
            s = getchar();
        }
        x *= f;
    }
    
    signed main()
    {
        int n, m;
        read(n);
    
        vector<int> a(n + 2);
        vector<int> prexor(n + 2);
        for (int i = 1; i <= n; i++)
            read(a[i]);
        for (int i = 1; i <= n; i++)
            prexor[i] = prexor[i - 1] ^ a[i];
    
        read(m);
        vector<int> ans(m + 2);
        vector<Question> questions(m + 2);
        for (int i = 1; i <= m; i++)
        {
            Question &question = questions[i];
            read(question.l);
            read(question.r);
            question.id = i;
            ans[i] = prexor[question.r] ^ prexor[question.l - 1];
        }
    
        vector<vector<Question>> asks(n + 2);
        for (int i = 1; i <= m; i++)
        {
            asks[questions[i].l].push_back(questions[i]);
        }
    
        BinaryIndexTree bit(n);
        map<int, int> last_pos;
        for (int i = n; i >= 1; i--)
        {
            int now = a[i];
            int &t = last_pos[now];
            if (t)
            {
                bit.add(t, now);
            }
            (t) = i;
            bit.add(i, now);
            for (const auto &question : asks[i])
            {
                ans[question.id] ^= bit.sum(question.r);
            }
        }
    
        for (int i = 1; i <= m; i++)
            printf("%d
    ", ans[i]);
    }
    
  • 相关阅读:
    数组模拟队列
    数组模拟栈
    数组实现双链表
    别再傻傻地说电脑内存不够用了,望周知!
    电脑内存又不够了?六个方法拯救你的C盘!
    jsp基础语法与指令
    最新的web.xml配置代码
    浅谈Session技术
    浅谈cookie技术
    Javaweb编程之Response下载文件
  • 原文地址:https://www.cnblogs.com/mollnn/p/14358625.html
Copyright © 2020-2023  润新知