链接:https://ac.nowcoder.com/acm/contest/1084/B
来源:牛客网

Galahad

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

本题推荐BGM:Galahad and Scientific Witchery

魔女要测试骑士的能力,要求他维护一个长度为 的序列,每次要询问一个区间的和。

但是魔女觉得太简单了,骑士能轻松记住 个数作为前缀和。

于是,魔女要求他回答一个区间的和,但如果某一个数在这个区间出现了多次,这个数只能被计算一次。

输入描述:

第一行两个整数 ,表示数列长度和询问个数。第二行 个整数,第i个整数为ai(1≤ai≤500 000)a_i(1\le a_i\le500\ 000)ai​(1≤ai​≤500 000),表示序列中的第i项。接下来 行,每行两个整数  ,表示询问的区间。

输出描述:

输出 行,每行一个整数表示这次询问的答案。

示例1

输入

复制

5 3
1 3 3 2 1
1 5
1 3
2 4

输出

复制

6
4
5

注意到这样一个事实:如果我当前询问的区间右端点为r,左端点为l,那么在这个区间内,所有元素,我都只需要保存它最后一次出现的位置就可以了。所以可以先离线询问,然后对每个询问的右端点排序,用树状数组维护区间和,从第一个元素开始,如果遇到之前出现过的元素,就将之前的元素删除,并把现在这个元素加入树状数组中,如果当前元素为区间右端点时,直接求和得到答案。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
struct Query{int l,r,id;
}Q[maxn];
ll s[maxn];
int pos[maxn];
int n,m;
int a[maxn];
ll ans[maxn];
int lowbit(int x){return x&-x;
}
void add(int x,int d){while(x<=n){s[x]+=d;x+=lowbit(x);}
}
ll sum(int x){ll res=0;while(x){res+=s[x];x-=lowbit(x);}return res;
}
int cmp(const Query a,const Query b){return a.r<b.r||(a.r==b.r&&a.l<b.l);
}signed main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=m;i++){scanf("%d%d",&Q[i].l,&Q[i].r);Q[i].id=i;}sort(Q+1,Q+m+1,cmp);for(int i=1;i<=n;i++)s[i]=0;int i=1;int now=1;while(i<=n){while(now<=Q[i].r){if(pos[a[now]]!=0){add(pos[a[now]],-a[now]);//删除之前出现过的数add(now,a[now]);pos[a[now]]=now;}else{pos[a[now]]=now;add(now,a[now]);}if(now==Q[i].r){ans[Q[i].id]=sum(Q[i].r)-sum(Q[i].l-1);break;}now++;}i++;}for(i=1;i<=m;i++){printf("%lld\n",ans[i]);}return 0;
}

牛客练习赛52.Galahad(树状数组维护区间不相同数的和)相关推荐

  1. 牛客练习赛52 BGalahad 树状数组

    传送门 题意: 求一个区间的和,但如果某一个数在这个区间出现了多次,这个数只能被计算一次. 官方题解:按右端点从小到大排序.建立树状数组ccc,维护贡献的前缀和. 由于权值ai 满足1≤ai≤500  ...

  2. 牛客练习赛22 E 树状数组 + DFS + 拓展欧几里德定理

    题目链接 题意: 给定一个长度为nnn的序列,进行mmm次操作,操作有两类: 111 LLL RRR vvv : 区间[L,R][L, R][L,R]的每个数加上vvv 222 LLL RRR ppp ...

  3. 树状数组维护区间和的模型及其拓广的简单总结

    by wyl8899 树状数组的基本知识已经被讲到烂了,我就不多说了,下面直接给出基本操作的代码. 假定原数组为a[1..n],树状数组b[1..n],考虑灵活性的需要,代码使用int *a传数组. ...

  4. 牛客练习赛52 B:Galahad(树状数组维护区间不同元素和(个数))

    [题目] 查询区间和,如果区间元素重复出现则计数一次. [题解] 按区间的右端点建立树状数组,维护区间[1,R]的每个元素的最右位置.按查询区间的右端点排序,依次处理,每次更新当前值的最右位置即可. ...

  5. ZOJ - 4117 BaoBao Loves Reading(树状数组求区间内不同数的个数+思维)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,其意义为第 i 秒需要看第 a[ i ] 种书,书架上可以供应无限种书,但是书桌有容量,当书桌上的容量达到上限后,如果还想从书架上拿新书来看, ...

  6. HDU 5465 Clarke and puzzle (二维树状数组维护区间异或)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5465 解题思路: 因为要对大量的区间进行异或,所以考虑用二维树状数组就行维护. #include< ...

  7. 牛客练习赛52 B Galahad (树状数组)

    题目链接:https://ac.nowcoder.com/acm/contest/1084/B 题意 5e5的区间,5e5个询求[l,r]区间内出现过的数的和 思路 1s时限,莫队显然会T 我们可以将 ...

  8. 树状数组求区间和模板 区间可修改 参考题目:牛客小白月赛 I 区间

    从前有个东西叫树状数组,它可以轻易实现一些简单的序列操作,比如单点修改,区间求和;区间修改,单点求值等. 但是我们经常需要更高级的操作,比如区间修改区间查询.这时候树状数组就不起作用了,只能选择写一个 ...

  9. 牛客练习赛52 | C | [烹饪] (DP,裴蜀定理,gcd)

    牛客练习赛52 C 烹饪 链接:https://ac.nowcoder.com/acm/contest/1084/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 327 ...

最新文章

  1. Java数据结构和算法的数组
  2. mysql switch binlog_如何使用 Golang 处理 MySQL 的 binlog
  3. (7)Java数据结构--集合map,set,list详解
  4. CG-CTF-Web-php decode
  5. mysql外表内表_mysql 子查询 将最外表带入子查询内2层 的另一种解决方法
  6. Codeforces Round #639 (Div. 2)(AB)
  7. Bootstrap带下拉的胶囊导航
  8. MyBatis基础入门《十七》动态SQL
  9. IDEA配置TeaVM插件
  10. 结构变量输入不正确的顺序可能会导致不正确的操作结果
  11. 3.9MB超小超强文本识别模型,支持20000个字符的识别,平安产险提出Hamming OCR
  12. React学习笔记(番外一)——video.js视频播放组件的入门及排坑经历
  13. android 全屏时钟,手机全屏数字时钟软件
  14. [物联网+云存储]-关于人工智能开关的学习思路
  15. 额~~~字符表情大全(写博客需要)
  16. 当“长期主义”遇上“流量生意”,轻松筹与水滴筹谁更胜一筹?
  17. Ajax同步获取数据
  18. JavaScript之childNodes 和 children 区别
  19. Mysql配置文件my.cnf配置及配置参数详解
  20. node.js+Vue计算机毕设项目基于Web的软考题库平台(程序+LW+部署)

热门文章

  1. 第1章 对象入门——Thinking-in-Java
  2. FSM——squirrel状态机使用
  3. Redis 持久化——RDB 详解
  4. TPM、TCM分别是什么?
  5. matlab设置列宽,matlab和Excel的交互-(2-单元格操作)
  6. Android在虚拟机和安卓机上运行不了
  7. c语言延时100us程序,编写100MS软件延时程序 汇编语言编写延时程序
  8. 计算机维修工文明操作,初级计算机维修工操作题.doc
  9. WebService 及java网络编程等基础概念(一)
  10. JAVA 垃圾回收