首页 > 其他分享 >【树状数组】牛客练习赛52 B.Galahad

【树状数组】牛客练习赛52 B.Galahad

时间:2023-08-26 18:33:18浏览次数:50  
标签:练习赛 vis int ++ 52 牛客 add vector fen

【树状数组】牛客练习赛52 B.Galahad

题目链接:https://ac.nowcoder.com/acm/contest/1084/B

题意

多组询问,计算区间和,但相同的数只能被计算一次。

题解

  1. 离线处理询问,按右端点排序。
  2. 对于相同的数字,我们只能选一个加入到区间和中,我们是枚举右端点,所以选择最靠近右端点左边的数字最优。所以每次在树状数组加入当前数字时,在上一次加入这个数字的位置把它删掉。具体见代码。

代码

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

template <typename T>
struct Fenwick {
    int n;
    vector<T> a;
    Fenwick(int n = 0) : n(n), a(n, T()) {}
    void add(int x, T d) {
        for (int i = x + 1; i <= n; i += i & -i) {
            a[i - 1] += d;
        }
    }
    T sum(int x) {
        auto ans = T();
        for (int i = x; i >= 1; i -= i & -i) {
            ans += a[i - 1];
        }
        return ans;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    vector<vector<pair<int, int>>> qry(n);
    for (int i = 0; i < m; i++) {
        int l, r;
        cin >> l >> r;
        l--, r--;
        qry[r].push_back({l, i});
    }

    int mx = *max_element(a.begin(), a.end());
    vector<int> vis(mx + 1, -1);

    vector<i64> ans(m);
    Fenwick<i64> fen(n + 2);
    for (int i = 0; i < n; i++) {
        if (vis[a[i]] != -1) {
            fen.add(vis[a[i]], -a[i]);
        }
        fen.add(i, a[i]);
        vis[a[i]] = i;

        for (auto [l, id] : qry[i]) {
            ans[id] = fen.sum(i + 1) - fen.sum(l);
        }
    }

    for (int i = 0; i < m; i++) {
        cout << ans[i] << '\n';
    }

    return 0;
}

末尾

把加入树状数组的数字改为加入1,即可求区间出现的数的种类。

即:

Fenwick<i64> fen(n + 2);
for (int i = 0; i < n; i++) {
    if (vis[a[i]] != -1) {
        fen.add(vis[a[i]], -1); //this
    }
    fen.add(i, 1); //this
    vis[a[i]] = i;
    for (auto [l, id] : qry[i]) {
        ans[id] = fen.sum(i + 1) - fen.sum(l);
    }
}

标签:练习赛,vis,int,++,52,牛客,add,vector,fen
From: https://www.cnblogs.com/blockche/p/17659263.html

相关文章

  • 1152 Google Recruitment
    题目:InJuly2004,GooglepostedonagiantbillboardalongHighway101inSiliconValley(showninthepicturebelow)forrecruitment.Thecontentissuper-simple,aURLconsistingofthefirst10-digitprimefoundinconsecutivedigitsofthenaturalcon......
  • P3521 [POI2011] ROT-Tree Rotations
    P3521[POI2011]ROT-TreeRotations首先合并两棵子树的时候只关心子树内值的个数,并不关心子树内具体是什么顺序,引导从下向上线段树合并计算代价。每一个值只会出现一次,首先每个叶子节点开一棵动态开点值域为\(1-n\)的线段树维护,初始只有自己的值的位置为\(1\)。然后对于每......
  • 牛客练习赛114 D题题解
    比赛编号太臭了题目链接对一第一组数据,我们形象化的得到下图:如何拆解使其变成一个“顺子”呢,我们像这样:贪心的从后往前取,对于取数列时的终点也就是枚举的起点如果不为0,就向前一直取,如果取到一个数\(x\)发现这个数的个数\(num_x\)是大于\(num_{x-1}\)的,就停止,最后看拆......
  • 2019年牛客普及模拟赛5
    字符统计:给出一个只包含空格和小写字母的字符串,问出现次数最多的字符(多个字符按照字典序输出)签到题。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;intsum[250];charans[250];signedmain(){ //freopen("T1.in","r",stdin); //freopen("T1.out"......
  • python调用SAP脚本下载库存报表MB52
    importmathimportos,sys,win32com.clientimportclipboardfrompprintimportpprintimportcsvdefget_mb52(session,args={},plant='0001'):result=download_from_sap(session,args=args,plant=plant)ifnotresult:#n......
  • 69th 2023/8/18 模拟赛总结52
    本次再次爆零,甚至原因都差不多又是因为想切题,又是T2,又是熟悉的2个半小时,硬刚一道题,下场惨烈这一次开始思索原因,自己在开打T2之前,选择相信了直觉,没有先将思路过一遍脑子再开始打这次的看题+思考时间有足足50分钟,到了8点40才开题,然后再加上T2调了一会,发现打完后只剩1h发现只......
  • 一个意外错误使你无法创建该文件。如果你继续收到此错误,可以使用错误代码来搜索有关此
     解决方法:正确方法应该是以管理员权限打开cmd,然后执行 icaclsc:\/setintegritylevelM ......
  • 牛客七夕比赛 题解
    标准的算法竞赛题有下面几个,写这篇博客主要是这个M很有意思,一直没绕过来这个弯如果你有更牛逼的构造方法欢迎交流指导。B构造边长为\(n\)的矩阵,使得每个\(2\times2\)的子矩形的权值和的极差最小两个指针L=1,R=\(n^2\)。将网格黑白染色后按照顺序遍历,黑色填\(R\)......
  • AOJ0525(bitset, 穷举)
    这题有3点要注意:1.thefliporderisnotrelatedtoresult.2.whywecansimplycounttomaximumofnumbereachcolumn?Imagineonlymanipulatetherow,itiseasytounderstandthatitisunnecessarytoflipthemratherthancountthemaximumside.3.Aga......
  • POJ1852(Ant)
    很久没写了,第一个程序。注意每个case前都要初始化//#defineLOCAL#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;intmain(){#ifdefLOCALfreopen("data.in","r",stdin);//freopen("datd.out&qu......